blob: 5a26d675a2c392d22f709e9fe318715d77afff4a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddie1892a52015-12-15 15:01:01 +05302 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530176/*
177 * Values for Mac spoofing feature
178 *
179 */
180#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
181#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
182#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530183#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
184
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530185
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530186static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700187{
188 WLAN_CIPHER_SUITE_WEP40,
189 WLAN_CIPHER_SUITE_WEP104,
190 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800191#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700192#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
193 WLAN_CIPHER_SUITE_KRK,
194 WLAN_CIPHER_SUITE_CCMP,
195#else
196 WLAN_CIPHER_SUITE_CCMP,
197#endif
198#ifdef FEATURE_WLAN_WAPI
199 WLAN_CIPHER_SUITE_SMS4,
200#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700201#ifdef WLAN_FEATURE_11W
202 WLAN_CIPHER_SUITE_AES_CMAC,
203#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700204};
205
206static inline int is_broadcast_ether_addr(const u8 *addr)
207{
208 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
209 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
210}
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
300 .band = IEEE80211_BAND_2GHZ,
301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
319 .band = IEEE80211_BAND_5GHZ,
320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
419/* By default, only single channel concurrency is allowed */
420static struct ieee80211_iface_combination
421wlan_hdd_iface_combination = {
422 .limits = wlan_hdd_iface_limit,
423 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800424 /*
425 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
426 * and p2p0 interfaces during driver init
427 * Some vendors create separate interface for P2P operations.
428 * wlan0: STA interface
429 * p2p0: P2P Device interface, action frames goes
430 * through this interface.
431 * p2p-xx: P2P interface, After GO negotiation this interface is
432 * created for p2p operations(GO/CLIENT interface).
433 */
434 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800435 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
436 .beacon_int_infra_match = false,
437};
438#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800439
Jeff Johnson295189b2012-06-20 16:38:30 -0700440static struct cfg80211_ops wlan_hdd_cfg80211_ops;
441
442/* Data rate 100KBPS based on IE Index */
443struct index_data_rate_type
444{
445 v_U8_t beacon_rate_index;
446 v_U16_t supported_rate[4];
447};
448
449/* 11B, 11G Rate table include Basic rate and Extended rate
450 The IDX field is the rate index
451 The HI field is the rate when RSSI is strong or being ignored
452 (in this case we report actual rate)
453 The MID field is the rate when RSSI is moderate
454 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
455 The LO field is the rate when RSSI is low
456 (in this case we don't report rates, actual current rate used)
457 */
458static const struct
459{
460 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700461 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700462} supported_data_rate[] =
463{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700464/* IDX HI HM LM LO (RSSI-based index */
465 {2, { 10, 10, 10, 0}},
466 {4, { 20, 20, 10, 0}},
467 {11, { 55, 20, 10, 0}},
468 {12, { 60, 55, 20, 0}},
469 {18, { 90, 55, 20, 0}},
470 {22, {110, 55, 20, 0}},
471 {24, {120, 90, 60, 0}},
472 {36, {180, 120, 60, 0}},
473 {44, {220, 180, 60, 0}},
474 {48, {240, 180, 90, 0}},
475 {66, {330, 180, 90, 0}},
476 {72, {360, 240, 90, 0}},
477 {96, {480, 240, 120, 0}},
478 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700479};
480
481/* MCS Based rate table */
482static struct index_data_rate_type supported_mcs_rate[] =
483{
484/* MCS L20 L40 S20 S40 */
485 {0, {65, 135, 72, 150}},
486 {1, {130, 270, 144, 300}},
487 {2, {195, 405, 217, 450}},
488 {3, {260, 540, 289, 600}},
489 {4, {390, 810, 433, 900}},
490 {5, {520, 1080, 578, 1200}},
491 {6, {585, 1215, 650, 1350}},
492 {7, {650, 1350, 722, 1500}}
493};
494
Leo Chang6f8870f2013-03-26 18:11:36 -0700495#ifdef WLAN_FEATURE_11AC
496
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530497#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700498
499struct index_vht_data_rate_type
500{
501 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530502 v_U16_t supported_VHT80_rate[2];
503 v_U16_t supported_VHT40_rate[2];
504 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700505};
506
507typedef enum
508{
509 DATA_RATE_11AC_MAX_MCS_7,
510 DATA_RATE_11AC_MAX_MCS_8,
511 DATA_RATE_11AC_MAX_MCS_9,
512 DATA_RATE_11AC_MAX_MCS_NA
513} eDataRate11ACMaxMcs;
514
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530515/* SSID broadcast type */
516typedef enum eSSIDBcastType
517{
518 eBCAST_UNKNOWN = 0,
519 eBCAST_NORMAL = 1,
520 eBCAST_HIDDEN = 2,
521} tSSIDBcastType;
522
Leo Chang6f8870f2013-03-26 18:11:36 -0700523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
c_hpothu79aab322014-07-14 21:11:01 +0530540/*array index points to MCS and array value points respective rssi*/
541static int rssiMcsTbl[][10] =
542{
543/*MCS 0 1 2 3 4 5 6 7 8 9*/
544 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
545 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
546 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
547};
548
Jeff Johnson295189b2012-06-20 16:38:30 -0700549extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530550#ifdef FEATURE_WLAN_SCAN_PNO
551static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
552#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700553
Leo Chang9056f462013-08-01 19:21:11 -0700554#ifdef WLAN_NL80211_TESTMODE
555enum wlan_hdd_tm_attr
556{
557 WLAN_HDD_TM_ATTR_INVALID = 0,
558 WLAN_HDD_TM_ATTR_CMD = 1,
559 WLAN_HDD_TM_ATTR_DATA = 2,
560 WLAN_HDD_TM_ATTR_TYPE = 3,
561 /* keep last */
562 WLAN_HDD_TM_ATTR_AFTER_LAST,
563 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
564};
565
566enum wlan_hdd_tm_cmd
567{
568 WLAN_HDD_TM_CMD_WLAN_HB = 1,
569};
570
571#define WLAN_HDD_TM_DATA_MAX_LEN 5000
572
573static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
574{
575 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
576 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
577 .len = WLAN_HDD_TM_DATA_MAX_LEN },
578};
579#endif /* WLAN_NL80211_TESTMODE */
580
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800581#ifdef FEATURE_WLAN_CH_AVOID
582/*
583 * FUNCTION: wlan_hdd_send_avoid_freq_event
584 * This is called when wlan driver needs to send vendor specific
585 * avoid frequency range event to userspace
586 */
587int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
588 tHddAvoidFreqList *pAvoidFreqList)
589{
590 struct sk_buff *vendor_event;
591
592 ENTER();
593
594 if (!pHddCtx)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
597 "%s: HDD context is null", __func__);
598 return -1;
599 }
600
601 if (!pAvoidFreqList)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
604 "%s: pAvoidFreqList is null", __func__);
605 return -1;
606 }
607
608 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
610 NULL,
611#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530613 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800614 GFP_KERNEL);
615 if (!vendor_event)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
618 "%s: cfg80211_vendor_event_alloc failed", __func__);
619 return -1;
620 }
621
622 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
623 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
624
625 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
626
627 EXIT();
628 return 0;
629}
630#endif /* FEATURE_WLAN_CH_AVOID */
631
Srinivas Dasari030bad32015-02-18 23:23:54 +0530632/*
633 * FUNCTION: __wlan_hdd_cfg80211_nan_request
634 * This is called when wlan driver needs to send vendor specific
635 * nan request event.
636 */
637static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
638 struct wireless_dev *wdev,
639 const void *data, int data_len)
640{
641 tNanRequestReq nan_req;
642 VOS_STATUS status;
643 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530644 struct net_device *dev = wdev->netdev;
645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530647 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
648
649 if (0 == data_len)
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("NAN - Invalid Request, length = 0"));
653 return ret_val;
654 }
655
656 if (NULL == data)
657 {
658 hddLog(VOS_TRACE_LEVEL_ERROR,
659 FL("NAN - Invalid Request, data is NULL"));
660 return ret_val;
661 }
662
663 status = wlan_hdd_validate_context(pHddCtx);
664 if (0 != status)
665 {
666 hddLog(VOS_TRACE_LEVEL_ERROR,
667 FL("HDD context is not valid"));
668 return -EINVAL;
669 }
670
671 hddLog(LOG1, FL("Received NAN command"));
672 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
673 (tANI_U8 *)data, data_len);
674
675 /* check the NAN Capability */
676 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("NAN is not supported by Firmware"));
680 return -EINVAL;
681 }
682
683 nan_req.request_data_len = data_len;
684 nan_req.request_data = data;
685
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530686 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530687 if (VOS_STATUS_SUCCESS == status)
688 {
689 ret_val = 0;
690 }
691 return ret_val;
692}
693
694/*
695 * FUNCTION: wlan_hdd_cfg80211_nan_request
696 * Wrapper to protect the nan vendor command from ssr
697 */
698static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
699 struct wireless_dev *wdev,
700 const void *data, int data_len)
701{
702 int ret;
703
704 vos_ssr_protect(__func__);
705 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
706 vos_ssr_unprotect(__func__);
707
708 return ret;
709}
710
711/*
712 * FUNCTION: wlan_hdd_cfg80211_nan_callback
713 * This is a callback function and it gets called
714 * when we need to report nan response event to
715 * upper layers.
716 */
717static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
718{
719 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
720 struct sk_buff *vendor_event;
721 int status;
722 tSirNanEvent *data;
723
724 ENTER();
725 if (NULL == msg)
726 {
727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 FL(" msg received here is null"));
729 return;
730 }
731 data = msg;
732
733 status = wlan_hdd_validate_context(pHddCtx);
734
735 if (0 != status)
736 {
737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 FL("HDD context is not valid"));
739 return;
740 }
741
742 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
744 NULL,
745#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530746 data->event_data_len +
747 NLMSG_HDRLEN,
748 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
749 GFP_KERNEL);
750
751 if (!vendor_event)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("cfg80211_vendor_event_alloc failed"));
755 return;
756 }
757 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
758 data->event_data_len, data->event_data))
759 {
760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
761 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
762 kfree_skb(vendor_event);
763 return;
764 }
765 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
766 EXIT();
767}
768
769/*
770 * FUNCTION: wlan_hdd_cfg80211_nan_init
771 * This function is called to register the callback to sme layer
772 */
773inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
774{
775 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
776}
777
778
Sunil Duttc69bccb2014-05-26 21:30:20 +0530779#ifdef WLAN_FEATURE_LINK_LAYER_STATS
780
781static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
782 struct sk_buff *vendor_event)
783{
784 if (nla_put_u8(vendor_event,
785 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
786 stats->rate.preamble) ||
787 nla_put_u8(vendor_event,
788 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
789 stats->rate.nss) ||
790 nla_put_u8(vendor_event,
791 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
792 stats->rate.bw) ||
793 nla_put_u8(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
795 stats->rate.rateMcsIdx) ||
796 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
797 stats->rate.bitrate ) ||
798 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
799 stats->txMpdu ) ||
800 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
801 stats->rxMpdu ) ||
802 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
803 stats->mpduLost ) ||
804 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
805 stats->retries) ||
806 nla_put_u32(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
808 stats->retriesShort ) ||
809 nla_put_u32(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
811 stats->retriesLong))
812 {
813 hddLog(VOS_TRACE_LEVEL_ERROR,
814 FL("QCA_WLAN_VENDOR_ATTR put fail"));
815 return FALSE;
816 }
817 return TRUE;
818}
819
820static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
821 struct sk_buff *vendor_event)
822{
823 u32 i = 0;
824 struct nlattr *rateInfo;
825 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
826 stats->type) ||
827 nla_put(vendor_event,
828 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
829 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
830 nla_put_u32(vendor_event,
831 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
832 stats->capabilities) ||
833 nla_put_u32(vendor_event,
834 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
835 stats->numRate))
836 {
837 hddLog(VOS_TRACE_LEVEL_ERROR,
838 FL("QCA_WLAN_VENDOR_ATTR put fail"));
839 goto error;
840 }
841
842 rateInfo = nla_nest_start(vendor_event,
843 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530844 if(!rateInfo)
845 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530846 for (i = 0; i < stats->numRate; i++)
847 {
848 struct nlattr *rates;
849 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
850 stats->rateStats +
851 (i * sizeof(tSirWifiRateStat)));
852 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530853 if(!rates)
854 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530855
856 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR,
859 FL("QCA_WLAN_VENDOR_ATTR put fail"));
860 return FALSE;
861 }
862 nla_nest_end(vendor_event, rates);
863 }
864 nla_nest_end(vendor_event, rateInfo);
865
866 return TRUE;
867error:
868 return FALSE;
869}
870
871static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
872 struct sk_buff *vendor_event)
873{
874 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
875 stats->ac ) ||
876 nla_put_u32(vendor_event,
877 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
878 stats->txMpdu ) ||
879 nla_put_u32(vendor_event,
880 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
881 stats->rxMpdu ) ||
882 nla_put_u32(vendor_event,
883 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
884 stats->txMcast ) ||
885 nla_put_u32(vendor_event,
886 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
887 stats->rxMcast ) ||
888 nla_put_u32(vendor_event,
889 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
890 stats->rxAmpdu ) ||
891 nla_put_u32(vendor_event,
892 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
893 stats->txAmpdu ) ||
894 nla_put_u32(vendor_event,
895 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
896 stats->mpduLost )||
897 nla_put_u32(vendor_event,
898 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
899 stats->retries ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
902 stats->retriesShort ) ||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
905 stats->retriesLong ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
908 stats->contentionTimeMin ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
911 stats->contentionTimeMax ) ||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
914 stats->contentionTimeAvg ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
917 stats->contentionNumSamples ))
918 {
919 hddLog(VOS_TRACE_LEVEL_ERROR,
920 FL("QCA_WLAN_VENDOR_ATTR put fail") );
921 return FALSE;
922 }
923 return TRUE;
924}
925
926static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
927 struct sk_buff *vendor_event)
928{
Dino Myclec8f3f332014-07-21 16:48:27 +0530929 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
931 nla_put(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
933 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
934 nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
936 stats->state ) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
939 stats->roaming ) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
942 stats->capabilities ) ||
943 nla_put(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
945 strlen(stats->ssid), stats->ssid) ||
946 nla_put(vendor_event,
947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
948 WNI_CFG_BSSID_LEN, stats->bssid) ||
949 nla_put(vendor_event,
950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
951 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
952 nla_put(vendor_event,
953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
954 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
955 )
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR,
958 FL("QCA_WLAN_VENDOR_ATTR put fail") );
959 return FALSE;
960 }
961 return TRUE;
962}
963
Dino Mycle3b9536d2014-07-09 22:05:24 +0530964static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
965 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530966 struct sk_buff *vendor_event)
967{
968 int i = 0;
969 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
971 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530972 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530973
Sunil Duttc69bccb2014-05-26 21:30:20 +0530974 if (FALSE == put_wifi_interface_info(
975 &pWifiIfaceStat->info,
976 vendor_event))
977 {
978 hddLog(VOS_TRACE_LEVEL_ERROR,
979 FL("QCA_WLAN_VENDOR_ATTR put fail") );
980 return FALSE;
981
982 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
984 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
985 if (NULL == pWifiIfaceStatTL)
986 {
987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
988 return FALSE;
989 }
990
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530991 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
992 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
993 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
994 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
995
996 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
997 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301000
1001 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1002 {
1003 if (VOS_STATUS_SUCCESS ==
1004 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1005 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1006 {
1007 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1008 * obtained from TL structure
1009 */
1010
1011 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1012 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1014
Srinivas Dasari98947432014-11-07 19:41:24 +05301015 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1016 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1017 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1018 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1019 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1020 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1021 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1022 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301023
Srinivas Dasari98947432014-11-07 19:41:24 +05301024 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1025 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1026 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1027 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1028 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301032
Srinivas Dasari98947432014-11-07 19:41:24 +05301033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301041 }
1042 else
1043 {
1044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1045 }
1046
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1050 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1055 }
1056 else
1057 {
1058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1059 }
1060
1061
Sunil Duttc69bccb2014-05-26 21:30:20 +05301062
1063 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301064 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1065 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1066 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1068 pWifiIfaceStat->beaconRx) ||
1069 nla_put_u32(vendor_event,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1071 pWifiIfaceStat->mgmtRx) ||
1072 nla_put_u32(vendor_event,
1073 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1074 pWifiIfaceStat->mgmtActionRx) ||
1075 nla_put_u32(vendor_event,
1076 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1077 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301078 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301079 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1080 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301081 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301082 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1083 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301084 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301085 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1086 pWifiIfaceStat->rssiAck))
1087 {
1088 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301089 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1090 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301091 return FALSE;
1092 }
1093
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301094#ifdef FEATURE_EXT_LL_STAT
1095 /*
1096 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1097 * then host should send Leaky AP stats to upper layer,
1098 * otherwise no need to send these stats.
1099 */
1100 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1101 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1102 )
1103 {
1104 hddLog(VOS_TRACE_LEVEL_INFO,
1105 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1106 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1107 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1108 pWifiIfaceStat->leakyApStat.rx_leak_window,
1109 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1110 if (nla_put_u32(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1112 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1113 nla_put_u32(vendor_event,
1114 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1115 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1116 nla_put_u32(vendor_event,
1117 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1118 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1119 nla_put_u64(vendor_event,
1120 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1121 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1122 {
1123 hddLog(VOS_TRACE_LEVEL_ERROR,
1124 FL("EXT_LL_STAT put fail"));
1125 vos_mem_free(pWifiIfaceStatTL);
1126 return FALSE;
1127 }
1128 }
1129#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 wmmInfo = nla_nest_start(vendor_event,
1131 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301132 if(!wmmInfo)
1133 {
1134 vos_mem_free(pWifiIfaceStatTL);
1135 return FALSE;
1136 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 for (i = 0; i < WIFI_AC_MAX; i++)
1138 {
1139 struct nlattr *wmmStats;
1140 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301141 if(!wmmStats)
1142 {
1143 vos_mem_free(pWifiIfaceStatTL);
1144 return FALSE;
1145 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301146 if (FALSE == put_wifi_wmm_ac_stat(
1147 &pWifiIfaceStat->AccessclassStats[i],
1148 vendor_event))
1149 {
1150 hddLog(VOS_TRACE_LEVEL_ERROR,
1151 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301152 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301153 return FALSE;
1154 }
1155
1156 nla_nest_end(vendor_event, wmmStats);
1157 }
1158 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301159 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 return TRUE;
1161}
1162
1163static tSirWifiInterfaceMode
1164 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1165{
1166 switch (deviceMode)
1167 {
1168 case WLAN_HDD_INFRA_STATION:
1169 return WIFI_INTERFACE_STA;
1170 case WLAN_HDD_SOFTAP:
1171 return WIFI_INTERFACE_SOFTAP;
1172 case WLAN_HDD_P2P_CLIENT:
1173 return WIFI_INTERFACE_P2P_CLIENT;
1174 case WLAN_HDD_P2P_GO:
1175 return WIFI_INTERFACE_P2P_GO;
1176 case WLAN_HDD_IBSS:
1177 return WIFI_INTERFACE_IBSS;
1178 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301179 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301180 }
1181}
1182
1183static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1184 tpSirWifiInterfaceInfo pInfo)
1185{
1186 v_U8_t *staMac = NULL;
1187 hdd_station_ctx_t *pHddStaCtx;
1188 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1189 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1190
1191 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1192
1193 vos_mem_copy(pInfo->macAddr,
1194 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1195
1196 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1197 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1198 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1199 {
1200 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1201 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1202 {
1203 pInfo->state = WIFI_DISCONNECTED;
1204 }
1205 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1206 {
1207 hddLog(VOS_TRACE_LEVEL_ERROR,
1208 "%s: Session ID %d, Connection is in progress", __func__,
1209 pAdapter->sessionId);
1210 pInfo->state = WIFI_ASSOCIATING;
1211 }
1212 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1213 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1214 {
1215 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1216 hddLog(VOS_TRACE_LEVEL_ERROR,
1217 "%s: client " MAC_ADDRESS_STR
1218 " is in the middle of WPS/EAPOL exchange.", __func__,
1219 MAC_ADDR_ARRAY(staMac));
1220 pInfo->state = WIFI_AUTHENTICATING;
1221 }
1222 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1223 {
1224 pInfo->state = WIFI_ASSOCIATED;
1225 vos_mem_copy(pInfo->bssid,
1226 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1227 vos_mem_copy(pInfo->ssid,
1228 pHddStaCtx->conn_info.SSID.SSID.ssId,
1229 pHddStaCtx->conn_info.SSID.SSID.length);
1230 //NULL Terminate the string.
1231 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1232 }
1233 }
1234 vos_mem_copy(pInfo->countryStr,
1235 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1236
1237 vos_mem_copy(pInfo->apCountryStr,
1238 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1239
1240 return TRUE;
1241}
1242
1243/*
1244 * hdd_link_layer_process_peer_stats () - This function is called after
1245 * receiving Link Layer Peer statistics from FW.This function converts
1246 * the firmware data to the NL data and sends the same to the kernel/upper
1247 * layers.
1248 */
1249static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1250 v_VOID_t *pData)
1251{
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301253 tpSirWifiPeerStat pWifiPeerStat;
1254 tpSirWifiPeerInfo pWifiPeerInfo;
1255 struct nlattr *peerInfo;
1256 struct sk_buff *vendor_event;
1257 int status, i;
1258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301259 ENTER();
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 status = wlan_hdd_validate_context(pHddCtx);
1262 if (0 != status)
1263 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 return;
1265 }
1266
1267 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1268
1269 hddLog(VOS_TRACE_LEVEL_INFO,
1270 "LL_STATS_PEER_ALL : numPeers %u",
1271 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301272 /*
1273 * Allocate a size of 4096 for the peer stats comprising
1274 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1275 * sizeof (tSirWifiRateStat).Each field is put with an
1276 * NL attribute.The size of 4096 is considered assuming
1277 * that number of rates shall not exceed beyond 50 with
1278 * the sizeof (tSirWifiRateStat) being 32.
1279 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301280 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1281 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301282 if (!vendor_event)
1283 {
1284 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301285 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301286 __func__);
1287 return;
1288 }
1289 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301290 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1291 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1292 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301293 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1294 pWifiPeerStat->numPeers))
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1298 kfree_skb(vendor_event);
1299 return;
1300 }
1301
1302 peerInfo = nla_nest_start(vendor_event,
1303 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301304 if(!peerInfo)
1305 {
1306 hddLog(VOS_TRACE_LEVEL_ERROR,
1307 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1308 __func__);
1309 kfree_skb(vendor_event);
1310 return;
1311 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301312
1313 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1314 pWifiPeerStat->peerInfo);
1315
1316 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1317 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301318 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301319 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301320
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301321 if(!peers)
1322 {
1323 hddLog(VOS_TRACE_LEVEL_ERROR,
1324 "%s: peer stats put fail",
1325 __func__);
1326 kfree_skb(vendor_event);
1327 return;
1328 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301329 if (FALSE == put_wifi_peer_info(
1330 pWifiPeerInfo, vendor_event))
1331 {
1332 hddLog(VOS_TRACE_LEVEL_ERROR,
1333 "%s: put_wifi_peer_info put fail", __func__);
1334 kfree_skb(vendor_event);
1335 return;
1336 }
1337
1338 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1339 pWifiPeerStat->peerInfo +
1340 (i * sizeof(tSirWifiPeerInfo)) +
1341 (numRate * sizeof (tSirWifiRateStat)));
1342 nla_nest_end(vendor_event, peers);
1343 }
1344 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301345 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301346 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301347}
1348
1349/*
1350 * hdd_link_layer_process_iface_stats () - This function is called after
1351 * receiving Link Layer Interface statistics from FW.This function converts
1352 * the firmware data to the NL data and sends the same to the kernel/upper
1353 * layers.
1354 */
1355static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1356 v_VOID_t *pData)
1357{
1358 tpSirWifiIfaceStat pWifiIfaceStat;
1359 struct sk_buff *vendor_event;
1360 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1361 int status;
1362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301363 ENTER();
1364
Sunil Duttc69bccb2014-05-26 21:30:20 +05301365 status = wlan_hdd_validate_context(pHddCtx);
1366 if (0 != status)
1367 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301368 return;
1369 }
1370 /*
1371 * Allocate a size of 4096 for the interface stats comprising
1372 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1373 * assuming that all these fit with in the limit.Please take
1374 * a call on the limit based on the data requirements on
1375 * interface statistics.
1376 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301377 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1378 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301379 if (!vendor_event)
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301382 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301383 return;
1384 }
1385
1386 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1387
Dino Mycle3b9536d2014-07-09 22:05:24 +05301388
1389 if (FALSE == hdd_get_interface_info( pAdapter,
1390 &pWifiIfaceStat->info))
1391 {
1392 hddLog(VOS_TRACE_LEVEL_ERROR,
1393 FL("hdd_get_interface_info get fail") );
1394 kfree_skb(vendor_event);
1395 return;
1396 }
1397
1398 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1399 vendor_event))
1400 {
1401 hddLog(VOS_TRACE_LEVEL_ERROR,
1402 FL("put_wifi_iface_stats fail") );
1403 kfree_skb(vendor_event);
1404 return;
1405 }
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 hddLog(VOS_TRACE_LEVEL_INFO,
1408 "WMI_LINK_STATS_IFACE Data");
1409
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301410 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411
1412 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413}
1414
1415/*
1416 * hdd_link_layer_process_radio_stats () - This function is called after
1417 * receiving Link Layer Radio statistics from FW.This function converts
1418 * the firmware data to the NL data and sends the same to the kernel/upper
1419 * layers.
1420 */
1421static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1422 v_VOID_t *pData)
1423{
1424 int status, i;
1425 tpSirWifiRadioStat pWifiRadioStat;
1426 tpSirWifiChannelStats pWifiChannelStats;
1427 struct sk_buff *vendor_event;
1428 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1429 struct nlattr *chList;
1430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301431 ENTER();
1432
Sunil Duttc69bccb2014-05-26 21:30:20 +05301433 status = wlan_hdd_validate_context(pHddCtx);
1434 if (0 != status)
1435 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301436 return;
1437 }
1438 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1439
1440 hddLog(VOS_TRACE_LEVEL_INFO,
1441 "LL_STATS_RADIO"
1442 " radio is %d onTime is %u "
1443 " txTime is %u rxTime is %u "
1444 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301445 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301446 " onTimePnoScan is %u onTimeHs20 is %u "
1447 " numChannels is %u",
1448 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1449 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1450 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301451 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 pWifiRadioStat->onTimeRoamScan,
1453 pWifiRadioStat->onTimePnoScan,
1454 pWifiRadioStat->onTimeHs20,
1455 pWifiRadioStat->numChannels);
1456 /*
1457 * Allocate a size of 4096 for the Radio stats comprising
1458 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1459 * (tSirWifiChannelStats).Each channel data is put with an
1460 * NL attribute.The size of 4096 is considered assuming that
1461 * number of channels shall not exceed beyond 60 with the
1462 * sizeof (tSirWifiChannelStats) being 24 bytes.
1463 */
1464
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301465 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1466 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301467 if (!vendor_event)
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301470 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301471 return;
1472 }
1473
1474 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301475 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1476 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1477 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1479 pWifiRadioStat->radio) ||
1480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1482 pWifiRadioStat->onTime) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1485 pWifiRadioStat->txTime) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1488 pWifiRadioStat->rxTime) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1491 pWifiRadioStat->onTimeScan) ||
1492 nla_put_u32(vendor_event,
1493 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1494 pWifiRadioStat->onTimeNbd) ||
1495 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301496 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1497 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301498 nla_put_u32(vendor_event,
1499 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1500 pWifiRadioStat->onTimeRoamScan) ||
1501 nla_put_u32(vendor_event,
1502 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1503 pWifiRadioStat->onTimePnoScan) ||
1504 nla_put_u32(vendor_event,
1505 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1506 pWifiRadioStat->onTimeHs20) ||
1507 nla_put_u32(vendor_event,
1508 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1509 pWifiRadioStat->numChannels))
1510 {
1511 hddLog(VOS_TRACE_LEVEL_ERROR,
1512 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1513 kfree_skb(vendor_event);
1514 return ;
1515 }
1516
1517 chList = nla_nest_start(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301519 if(!chList)
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1523 __func__);
1524 kfree_skb(vendor_event);
1525 return;
1526 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301527 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1528 {
1529 struct nlattr *chInfo;
1530
1531 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1532 pWifiRadioStat->channels +
1533 (i * sizeof(tSirWifiChannelStats)));
1534
Sunil Duttc69bccb2014-05-26 21:30:20 +05301535 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301536 if(!chInfo)
1537 {
1538 hddLog(VOS_TRACE_LEVEL_ERROR,
1539 "%s: failed to put chInfo",
1540 __func__);
1541 kfree_skb(vendor_event);
1542 return;
1543 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544
1545 if (nla_put_u32(vendor_event,
1546 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1547 pWifiChannelStats->channel.width) ||
1548 nla_put_u32(vendor_event,
1549 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1550 pWifiChannelStats->channel.centerFreq) ||
1551 nla_put_u32(vendor_event,
1552 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1553 pWifiChannelStats->channel.centerFreq0) ||
1554 nla_put_u32(vendor_event,
1555 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1556 pWifiChannelStats->channel.centerFreq1) ||
1557 nla_put_u32(vendor_event,
1558 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1559 pWifiChannelStats->onTime) ||
1560 nla_put_u32(vendor_event,
1561 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1562 pWifiChannelStats->ccaBusyTime))
1563 {
1564 hddLog(VOS_TRACE_LEVEL_ERROR,
1565 FL("cfg80211_vendor_event_alloc failed") );
1566 kfree_skb(vendor_event);
1567 return ;
1568 }
1569 nla_nest_end(vendor_event, chInfo);
1570 }
1571 nla_nest_end(vendor_event, chList);
1572
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301573 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574
1575 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576 return;
1577}
1578
1579/*
1580 * hdd_link_layer_stats_ind_callback () - This function is called after
1581 * receiving Link Layer indications from FW.This callback converts the firmware
1582 * data to the NL data and send the same to the kernel/upper layers.
1583 */
1584static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1585 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301586 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301587{
Dino Mycled3d50022014-07-07 12:58:25 +05301588 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1589 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301590 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301591 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 int status;
1593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301594 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301596 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597 if (0 != status)
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 return;
1600 }
1601
Dino Mycled3d50022014-07-07 12:58:25 +05301602 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1603 if (NULL == pAdapter)
1604 {
1605 hddLog(VOS_TRACE_LEVEL_ERROR,
1606 FL(" MAC address %pM does not exist with host"),
1607 macAddr);
1608 return;
1609 }
1610
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301612 "%s: Interface: %s LLStats indType: %d", __func__,
1613 pAdapter->dev->name, indType);
1614
Sunil Duttc69bccb2014-05-26 21:30:20 +05301615 switch (indType)
1616 {
1617 case SIR_HAL_LL_STATS_RESULTS_RSP:
1618 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301620 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1621 "respId = %u, moreResultToFollow = %u",
1622 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1623 macAddr, linkLayerStatsResults->respId,
1624 linkLayerStatsResults->moreResultToFollow);
1625
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context = &pHddCtx->ll_stats_context;
1628 /* validate response received from target */
1629 if ((context->request_id != linkLayerStatsResults->respId) ||
1630 !(context->request_bitmap & linkLayerStatsResults->paramId))
1631 {
1632 spin_unlock(&hdd_context_lock);
1633 hddLog(LOGE,
1634 FL("Error : Request id %d response id %d request bitmap 0x%x"
1635 "response bitmap 0x%x"),
1636 context->request_id, linkLayerStatsResults->respId,
1637 context->request_bitmap, linkLayerStatsResults->paramId);
1638 return;
1639 }
1640 spin_unlock(&hdd_context_lock);
1641
Sunil Duttc69bccb2014-05-26 21:30:20 +05301642 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1643 {
1644 hdd_link_layer_process_radio_stats(pAdapter,
1645 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301646 spin_lock(&hdd_context_lock);
1647 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1648 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301649 }
1650 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1651 {
1652 hdd_link_layer_process_iface_stats(pAdapter,
1653 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301654 spin_lock(&hdd_context_lock);
1655 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1656 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301657 }
1658 else if ( linkLayerStatsResults->paramId &
1659 WMI_LINK_STATS_ALL_PEER )
1660 {
1661 hdd_link_layer_process_peer_stats(pAdapter,
1662 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301663 spin_lock(&hdd_context_lock);
1664 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1665 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301666 } /* WMI_LINK_STATS_ALL_PEER */
1667 else
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR,
1670 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1671 }
1672
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301673 spin_lock(&hdd_context_lock);
1674 /* complete response event if all requests are completed */
1675 if (0 == context->request_bitmap)
1676 complete(&context->response_event);
1677 spin_unlock(&hdd_context_lock);
1678
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679 break;
1680 }
1681 default:
1682 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1683 break;
1684 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301685
1686 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301687 return;
1688}
1689
1690const struct
1691nla_policy
1692qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1693{
1694 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1695 { .type = NLA_U32 },
1696 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1697 { .type = NLA_U32 },
1698};
1699
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301700static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1701 struct wireless_dev *wdev,
1702 const void *data,
1703 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704{
1705 int status;
1706 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301707 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301708 struct net_device *dev = wdev->netdev;
1709 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1710 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301712 ENTER();
1713
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 status = wlan_hdd_validate_context(pHddCtx);
1715 if (0 != status)
1716 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 return -EINVAL;
1718 }
1719
1720 if (NULL == pAdapter)
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR,
1723 FL("HDD adapter is Null"));
1724 return -ENODEV;
1725 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301726 /* check the LLStats Capability */
1727 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1728 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1729 {
1730 hddLog(VOS_TRACE_LEVEL_ERROR,
1731 FL("Link Layer Statistics not supported by Firmware"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734
1735 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1736 (struct nlattr *)data,
1737 data_len, qca_wlan_vendor_ll_set_policy))
1738 {
1739 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1740 return -EINVAL;
1741 }
1742 if (!tb_vendor
1743 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1744 {
1745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1746 return -EINVAL;
1747 }
1748 if (!tb_vendor[
1749 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1752 return -EINVAL;
1753 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301754 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756
Dino Mycledf0a5d92014-07-04 09:41:55 +05301757 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301758 nla_get_u32(
1759 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1760
Dino Mycledf0a5d92014-07-04 09:41:55 +05301761 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 nla_get_u32(
1763 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1764
Dino Mycled3d50022014-07-07 12:58:25 +05301765 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1766 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301767
1768
1769 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301770 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1771 "Statistics Gathering = %d ",
1772 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1773 linkLayerStatsSetReq.mpduSizeThreshold,
1774 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301775
1776 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1777 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301779 {
1780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1781 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 return -EINVAL;
1783
1784 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301785
Sunil Duttc69bccb2014-05-26 21:30:20 +05301786 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301787 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1790 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791 return -EINVAL;
1792 }
1793
1794 pAdapter->isLinkLayerStatsSet = 1;
1795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301796 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797 return 0;
1798}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301799static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1800 struct wireless_dev *wdev,
1801 const void *data,
1802 int data_len)
1803{
1804 int ret = 0;
1805
1806 vos_ssr_protect(__func__);
1807 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1808 vos_ssr_unprotect(__func__);
1809
1810 return ret;
1811}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812
1813const struct
1814nla_policy
1815qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1816{
1817 /* Unsigned 32bit value provided by the caller issuing the GET stats
1818 * command. When reporting
1819 * the stats results, the driver uses the same value to indicate
1820 * which GET request the results
1821 * correspond to.
1822 */
1823 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1824
1825 /* Unsigned 32bit value . bit mask to identify what statistics are
1826 requested for retrieval */
1827 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1828};
1829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301830static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1831 struct wireless_dev *wdev,
1832 const void *data,
1833 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301835 unsigned long rc;
1836 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301837 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301842 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 int status;
1844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL ;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_FATAL,
1856 "%s: HDD adapter is Null", __func__);
1857 return -ENODEV;
1858 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301859
1860 if (pHddStaCtx == NULL)
1861 {
1862 hddLog(VOS_TRACE_LEVEL_FATAL,
1863 "%s: HddStaCtx is Null", __func__);
1864 return -ENODEV;
1865 }
1866
Dino Mycledf0a5d92014-07-04 09:41:55 +05301867 /* check the LLStats Capability */
1868 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1869 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1870 {
1871 hddLog(VOS_TRACE_LEVEL_ERROR,
1872 FL("Link Layer Statistics not supported by Firmware"));
1873 return -EINVAL;
1874 }
1875
Sunil Duttc69bccb2014-05-26 21:30:20 +05301876
1877 if (!pAdapter->isLinkLayerStatsSet)
1878 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301879 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301880 "%s: isLinkLayerStatsSet : %d",
1881 __func__, pAdapter->isLinkLayerStatsSet);
1882 return -EINVAL;
1883 }
1884
Mukul Sharma10313ba2015-07-29 19:14:39 +05301885 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1886 {
1887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1888 "%s: Roaming in progress, so unable to proceed this request", __func__);
1889 return -EBUSY;
1890 }
1891
Sunil Duttc69bccb2014-05-26 21:30:20 +05301892 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1893 (struct nlattr *)data,
1894 data_len, qca_wlan_vendor_ll_get_policy))
1895 {
1896 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1897 return -EINVAL;
1898 }
1899
1900 if (!tb_vendor
1901 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1902 {
1903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1904 return -EINVAL;
1905 }
1906
1907 if (!tb_vendor
1908 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1909 {
1910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1911 return -EINVAL;
1912 }
1913
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914
Dino Mycledf0a5d92014-07-04 09:41:55 +05301915 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 nla_get_u32( tb_vendor[
1917 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 nla_get_u32( tb_vendor[
1920 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1921
Dino Mycled3d50022014-07-07 12:58:25 +05301922 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1923 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301926 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1927 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301928 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301930 spin_lock(&hdd_context_lock);
1931 context = &pHddCtx->ll_stats_context;
1932 context->request_id = linkLayerStatsGetReq.reqId;
1933 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1934 INIT_COMPLETION(context->response_event);
1935 spin_unlock(&hdd_context_lock);
1936
Sunil Duttc69bccb2014-05-26 21:30:20 +05301937 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301938 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301944
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301945 rc = wait_for_completion_timeout(&context->response_event,
1946 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1947 if (!rc)
1948 {
1949 hddLog(LOGE,
1950 FL("Target response timed out request id %d request bitmap 0x%x"),
1951 context->request_id, context->request_bitmap);
1952 return -ETIMEDOUT;
1953 }
1954
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301955 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301956 return 0;
1957}
1958
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
1972
Sunil Duttc69bccb2014-05-26 21:30:20 +05301973const struct
1974nla_policy
1975qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1976{
1977 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1979 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1980 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1981};
1982
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301983static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1984 struct wireless_dev *wdev,
1985 const void *data,
1986 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301987{
1988 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1989 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301990 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 struct net_device *dev = wdev->netdev;
1992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1993 u32 statsClearReqMask;
1994 u8 stopReq;
1995 int status;
1996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301997 ENTER();
1998
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999 status = wlan_hdd_validate_context(pHddCtx);
2000 if (0 != status)
2001 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302002 return -EINVAL;
2003 }
2004
2005 if (NULL == pAdapter)
2006 {
2007 hddLog(VOS_TRACE_LEVEL_FATAL,
2008 "%s: HDD adapter is Null", __func__);
2009 return -ENODEV;
2010 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302011 /* check the LLStats Capability */
2012 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2013 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2014 {
2015 hddLog(VOS_TRACE_LEVEL_ERROR,
2016 FL("Enable LLStats Capability"));
2017 return -EINVAL;
2018 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302019
2020 if (!pAdapter->isLinkLayerStatsSet)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: isLinkLayerStatsSet : %d",
2024 __func__, pAdapter->isLinkLayerStatsSet);
2025 return -EINVAL;
2026 }
2027
2028 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2029 (struct nlattr *)data,
2030 data_len, qca_wlan_vendor_ll_clr_policy))
2031 {
2032 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2033 return -EINVAL;
2034 }
2035
2036 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2037
2038 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2039 {
2040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2041 return -EINVAL;
2042
2043 }
2044
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 nla_get_u32(
2048 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2049
Dino Mycledf0a5d92014-07-04 09:41:55 +05302050 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051 nla_get_u8(
2052 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2053
2054 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302055 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056
Dino Mycled3d50022014-07-07 12:58:25 +05302057 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2058 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059
2060 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302061 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2062 "statsClearReqMask = 0x%X, stopReq = %d",
2063 linkLayerStatsClearReq.reqId,
2064 linkLayerStatsClearReq.macAddr,
2065 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302066 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067
2068 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302069 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302070 {
2071 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302072 hdd_station_ctx_t *pHddStaCtx;
2073
2074 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2075 if (VOS_STATUS_SUCCESS !=
2076 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2077 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2078 {
2079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2080 "WLANTL_ClearInterfaceStats Failed", __func__);
2081 return -EINVAL;
2082 }
2083 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2084 (statsClearReqMask & WIFI_STATS_IFACE)) {
2085 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2086 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2087 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2088 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2089 }
2090
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2092 2 * sizeof(u32) +
2093 NLMSG_HDRLEN);
2094
2095 if (temp_skbuff != NULL)
2096 {
2097
2098 if (nla_put_u32(temp_skbuff,
2099 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2100 statsClearReqMask) ||
2101 nla_put_u32(temp_skbuff,
2102 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2103 stopReq))
2104 {
2105 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2106 kfree_skb(temp_skbuff);
2107 return -EINVAL;
2108 }
2109 /* If the ask is to stop the stats collection as part of clear
2110 * (stopReq = 1) , ensure that no further requests of get
2111 * go to the firmware by having isLinkLayerStatsSet set to 0.
2112 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302113 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 * case the firmware is just asked to clear the statistics.
2115 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302116 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302117 pAdapter->isLinkLayerStatsSet = 0;
2118 return cfg80211_vendor_cmd_reply(temp_skbuff);
2119 }
2120 return -ENOMEM;
2121 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302122
2123 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302124 return -EINVAL;
2125}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302126static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2127 struct wireless_dev *wdev,
2128 const void *data,
2129 int data_len)
2130{
2131 int ret = 0;
2132
2133 vos_ssr_protect(__func__);
2134 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2135 vos_ssr_unprotect(__func__);
2136
2137 return ret;
2138
2139
2140}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2142
Dino Mycle6fb96c12014-06-10 11:52:40 +05302143#ifdef WLAN_FEATURE_EXTSCAN
2144static const struct nla_policy
2145wlan_hdd_extscan_config_policy
2146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2147{
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2151 { .type = NLA_U32 },
2152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2154 { .type = NLA_U32 },
2155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2157
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2162 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2164 { .type = NLA_U32 },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2166 { .type = NLA_U32 },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2168 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2172 { .type = NLA_U32 },
2173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2174 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2176 { .type = NLA_U8 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302178 { .type = NLA_U8 },
2179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2180 { .type = NLA_U8 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2182 { .type = NLA_U8 },
2183
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2185 { .type = NLA_U32 },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2187 { .type = NLA_UNSPEC },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2189 { .type = NLA_S32 },
2190 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2191 { .type = NLA_S32 },
2192 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2193 { .type = NLA_U32 },
2194 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2195 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302196 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2197 { .type = NLA_U32 },
2198 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2199 { .type = NLA_BINARY,
2200 .len = IEEE80211_MAX_SSID_LEN + 1 },
2201 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302202 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302203 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2204 { .type = NLA_U32 },
2205 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2206 { .type = NLA_U8 },
2207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2208 { .type = NLA_S32 },
2209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2210 { .type = NLA_S32 },
2211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2212 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302213};
2214
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302215/**
2216 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2217 * @ctx: hdd global context
2218 * @data: capabilities data
2219 *
2220 * Return: none
2221 */
2222static void
2223wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302224{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302225 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302226 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302227 tSirEXTScanCapabilitiesEvent *data =
2228 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302230 ENTER();
2231
2232 if (wlan_hdd_validate_context(pHddCtx))
2233 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302234 return;
2235 }
2236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302237 if (!pMsg)
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2240 return;
2241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302243 vos_spin_lock_acquire(&hdd_context_lock);
2244
2245 context = &pHddCtx->ext_scan_context;
2246 /* validate response received from target*/
2247 if (context->request_id != data->requestId)
2248 {
2249 vos_spin_lock_release(&hdd_context_lock);
2250 hddLog(LOGE,
2251 FL("Target response id did not match: request_id %d resposne_id %d"),
2252 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302253 return;
2254 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302255 else
2256 {
2257 context->capability_response = *data;
2258 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302259 }
2260
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302261 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302262
Dino Mycle6fb96c12014-06-10 11:52:40 +05302263 return;
2264}
2265
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302266/*
2267 * define short names for the global vendor params
2268 * used by wlan_hdd_send_ext_scan_capability()
2269 */
2270#define PARAM_REQUEST_ID \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2272#define PARAM_STATUS \
2273 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2274#define MAX_SCAN_CACHE_SIZE \
2275 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2276#define MAX_SCAN_BUCKETS \
2277 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2278#define MAX_AP_CACHE_PER_SCAN \
2279 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2280#define MAX_RSSI_SAMPLE_SIZE \
2281 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2282#define MAX_SCAN_RPT_THRHOLD \
2283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2284#define MAX_HOTLIST_BSSIDS \
2285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2286#define MAX_BSSID_HISTORY_ENTRIES \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2288#define MAX_HOTLIST_SSIDS \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302290#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302292
2293static int wlan_hdd_send_ext_scan_capability(void *ctx)
2294{
2295 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2296 struct sk_buff *skb = NULL;
2297 int ret;
2298 tSirEXTScanCapabilitiesEvent *data;
2299 tANI_U32 nl_buf_len;
2300
2301 ret = wlan_hdd_validate_context(pHddCtx);
2302 if (0 != ret)
2303 {
2304 return ret;
2305 }
2306
2307 data = &(pHddCtx->ext_scan_context.capability_response);
2308
2309 nl_buf_len = NLMSG_HDRLEN;
2310 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2311 (sizeof(data->status) + NLA_HDRLEN) +
2312 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2313 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2314 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2315 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2316 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2317 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2318 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2319 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2320
2321 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2322
2323 if (!skb)
2324 {
2325 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2326 return -ENOMEM;
2327 }
2328
2329 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2330 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2331 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2332 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2333 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2334 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2335 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2336 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2337
2338 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2339 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2340 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2341 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2342 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2343 data->maxApPerScan) ||
2344 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2345 data->maxRssiSampleSize) ||
2346 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2347 data->maxScanReportingThreshold) ||
2348 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2349 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2350 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302351 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2352 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302353 {
2354 hddLog(LOGE, FL("nla put fail"));
2355 goto nla_put_failure;
2356 }
2357
2358 cfg80211_vendor_cmd_reply(skb);
2359 return 0;
2360
2361nla_put_failure:
2362 kfree_skb(skb);
2363 return -EINVAL;;
2364}
2365
2366/*
2367 * done with short names for the global vendor params
2368 * used by wlan_hdd_send_ext_scan_capability()
2369 */
2370#undef PARAM_REQUEST_ID
2371#undef PARAM_STATUS
2372#undef MAX_SCAN_CACHE_SIZE
2373#undef MAX_SCAN_BUCKETS
2374#undef MAX_AP_CACHE_PER_SCAN
2375#undef MAX_RSSI_SAMPLE_SIZE
2376#undef MAX_SCAN_RPT_THRHOLD
2377#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302378#undef MAX_BSSID_HISTORY_ENTRIES
2379#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302380
2381static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2382{
2383 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2384 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302385 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302386 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302388 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302390 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302391 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302393 if (!pMsg)
2394 {
2395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 return;
2397 }
2398
Dino Mycle6fb96c12014-06-10 11:52:40 +05302399 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2400 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2401
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402 context = &pHddCtx->ext_scan_context;
2403 spin_lock(&hdd_context_lock);
2404 if (context->request_id == pData->requestId) {
2405 context->response_status = pData->status ? -EINVAL : 0;
2406 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302408 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409
2410 /*
2411 * Store the Request ID for comparing with the requestID obtained
2412 * in other requests.HDD shall return a failure is the extscan_stop
2413 * request is issued with a different requestId as that of the
2414 * extscan_start request. Also, This requestId shall be used while
2415 * indicating the full scan results to the upper layers.
2416 * The requestId is stored with the assumption that the firmware
2417 * shall return the ext scan start request's requestId in ext scan
2418 * start response.
2419 */
2420 if (pData->status == 0)
2421 pMac->sme.extScanStartReqId = pData->requestId;
2422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302423 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302424 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425}
2426
2427
2428static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2429{
2430 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2431 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302432 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302434 ENTER();
2435
2436 if (wlan_hdd_validate_context(pHddCtx)){
2437 return;
2438 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302439
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302440 if (!pMsg)
2441 {
2442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302443 return;
2444 }
2445
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302446 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2447 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302449 context = &pHddCtx->ext_scan_context;
2450 spin_lock(&hdd_context_lock);
2451 if (context->request_id == pData->requestId) {
2452 context->response_status = pData->status ? -EINVAL : 0;
2453 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302454 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302455 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302457 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302458 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459}
2460
Dino Mycle6fb96c12014-06-10 11:52:40 +05302461static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2462 void *pMsg)
2463{
2464 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302465 tpSirEXTScanSetBssidHotListRspParams pData =
2466 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302467 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302469 ENTER();
2470
2471 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472 return;
2473 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302475 if (!pMsg)
2476 {
2477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2478 return;
2479 }
2480
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302481 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2482 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302484 context = &pHddCtx->ext_scan_context;
2485 spin_lock(&hdd_context_lock);
2486 if (context->request_id == pData->requestId) {
2487 context->response_status = pData->status ? -EINVAL : 0;
2488 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302490 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302492 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302493 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494}
2495
2496static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2497 void *pMsg)
2498{
2499 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 tpSirEXTScanResetBssidHotlistRspParams pData =
2501 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302502 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302504 ENTER();
2505
2506 if (wlan_hdd_validate_context(pHddCtx)) {
2507 return;
2508 }
2509 if (!pMsg)
2510 {
2511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513 }
2514
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302515 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2516 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302517
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302518 context = &pHddCtx->ext_scan_context;
2519 spin_lock(&hdd_context_lock);
2520 if (context->request_id == pData->requestId) {
2521 context->response_status = pData->status ? -EINVAL : 0;
2522 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302523 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302524 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302526 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528}
2529
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302530static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2531 void *pMsg)
2532{
2533 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2534 tpSirEXTScanSetSsidHotListRspParams pData =
2535 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2536 struct hdd_ext_scan_context *context;
2537
2538 if (wlan_hdd_validate_context(pHddCtx)){
2539 return;
2540 }
2541
2542 if (!pMsg)
2543 {
2544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2545 return;
2546 }
2547
2548 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2549 pData->status);
2550
2551 context = &pHddCtx->ext_scan_context;
2552 spin_lock(&hdd_context_lock);
2553 if (context->request_id == pData->requestId) {
2554 context->response_status = pData->status ? -EINVAL : 0;
2555 complete(&context->response_event);
2556 }
2557 spin_unlock(&hdd_context_lock);
2558
2559 return;
2560}
2561
2562static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2563 void *pMsg)
2564{
2565 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2566 tpSirEXTScanResetSsidHotlistRspParams pData =
2567 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2568 struct hdd_ext_scan_context *context;
2569
2570 if (wlan_hdd_validate_context(pHddCtx)) {
2571 return;
2572 }
2573 if (!pMsg)
2574 {
2575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2576 return;
2577 }
2578
2579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2580 pData->status);
2581
2582 context = &pHddCtx->ext_scan_context;
2583 spin_lock(&hdd_context_lock);
2584 if (context->request_id == pData->requestId) {
2585 context->response_status = pData->status ? -EINVAL : 0;
2586 complete(&context->response_event);
2587 }
2588 spin_unlock(&hdd_context_lock);
2589
2590 return;
2591}
2592
2593
Dino Mycle6fb96c12014-06-10 11:52:40 +05302594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2595 void *pMsg)
2596{
2597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302600 tANI_S32 totalResults;
2601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2603 struct hdd_ext_scan_context *context;
2604 bool ignore_cached_results = false;
2605 tExtscanCachedScanResult *result;
2606 struct nlattr *nla_results;
2607 tANI_U16 ieLength= 0;
2608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302610 ENTER();
2611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302615 if (!pMsg)
2616 {
2617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2618 return;
2619 }
2620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 spin_lock(&hdd_context_lock);
2622 context = &pHddCtx->ext_scan_context;
2623 ignore_cached_results = context->ignore_cached_results;
2624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 if (ignore_cached_results) {
2627 hddLog(LOGE,
2628 FL("Ignore the cached results received after timeout"));
2629 return;
2630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2638 scan_id_index++) {
2639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302641 totalResults = result->num_results;
2642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2643 result->scan_id, result->flags, totalResults);
2644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302646 do{
2647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2653
2654 if (!skb) {
2655 hddLog(VOS_TRACE_LEVEL_ERROR,
2656 FL("cfg80211_vendor_event_alloc failed"));
2657 return;
2658 }
2659
2660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2661
2662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2663 pData->requestId) ||
2664 nla_put_u32(skb,
2665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2666 resultsPerEvent)) {
2667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2668 goto fail;
2669 }
2670 if (nla_put_u8(skb,
2671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302673 {
2674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2675 goto fail;
2676 }
2677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id)) {
2681 hddLog(LOGE, FL("put fail"));
2682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302685 nla_results = nla_nest_start(skb,
2686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2687 if (!nla_results)
2688 goto fail;
2689
2690 if (resultsPerEvent) {
2691 struct nlattr *aps;
2692 struct nlattr *nla_result;
2693
2694 nla_result = nla_nest_start(skb, scan_id_index);
2695 if(!nla_result)
2696 goto fail;
2697
2698 if (nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2700 result->scan_id) ||
2701 nla_put_u32(skb,
2702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2703 result->flags) ||
2704 nla_put_u32(skb,
2705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2706 totalResults)) {
2707 hddLog(LOGE, FL("put fail"));
2708 goto fail;
2709 }
2710
2711 aps = nla_nest_start(skb,
2712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2713 if (!aps)
2714 {
2715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2716 goto fail;
2717 }
2718
2719 head_ptr = (tpSirWifiScanResult) &(result->ap);
2720
2721 for (j = 0; j < resultsPerEvent; j++, i++) {
2722 struct nlattr *ap;
2723 pSirWifiScanResult = head_ptr + i;
2724
2725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05302726 * Firmware returns timestamp from extscan_start till
2727 * BSSID was cached (in micro seconds). Add this with
2728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302729 * to derive the time since boot when the
2730 * BSSID was cached.
2731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05302732 pSirWifiScanResult->ts +=
2733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2735 "Ssid (%s)"
2736 "Bssid: %pM "
2737 "Channel (%u)"
2738 "Rssi (%d)"
2739 "RTT (%u)"
2740 "RTT_SD (%u)"
2741 "Beacon Period %u"
2742 "Capability 0x%x "
2743 "Ie length %d",
2744 i,
2745 pSirWifiScanResult->ts,
2746 pSirWifiScanResult->ssid,
2747 pSirWifiScanResult->bssid,
2748 pSirWifiScanResult->channel,
2749 pSirWifiScanResult->rssi,
2750 pSirWifiScanResult->rtt,
2751 pSirWifiScanResult->rtt_sd,
2752 pSirWifiScanResult->beaconPeriod,
2753 pSirWifiScanResult->capability,
2754 ieLength);
2755
2756 ap = nla_nest_start(skb, j + 1);
2757 if (!ap)
2758 {
2759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2760 goto fail;
2761 }
2762
2763 if (nla_put_u64(skb,
2764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2765 pSirWifiScanResult->ts) )
2766 {
2767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2768 goto fail;
2769 }
2770 if (nla_put(skb,
2771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2772 sizeof(pSirWifiScanResult->ssid),
2773 pSirWifiScanResult->ssid) )
2774 {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2776 goto fail;
2777 }
2778 if (nla_put(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2780 sizeof(pSirWifiScanResult->bssid),
2781 pSirWifiScanResult->bssid) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2788 pSirWifiScanResult->channel) )
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_s32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2795 pSirWifiScanResult->rssi) )
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2802 pSirWifiScanResult->rtt) )
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2809 pSirWifiScanResult->rtt_sd))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814 if (nla_put_u32(skb,
2815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2816 pSirWifiScanResult->beaconPeriod))
2817 {
2818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2819 goto fail;
2820 }
2821 if (nla_put_u32(skb,
2822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2823 pSirWifiScanResult->capability))
2824 {
2825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2826 goto fail;
2827 }
2828 if (nla_put_u32(skb,
2829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2830 ieLength))
2831 {
2832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2833 goto fail;
2834 }
2835
2836 if (ieLength)
2837 if (nla_put(skb,
2838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2839 ieLength, ie)) {
2840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2841 goto fail;
2842 }
2843
2844 nla_nest_end(skb, ap);
2845 }
2846 nla_nest_end(skb, aps);
2847 nla_nest_end(skb, nla_result);
2848 }
2849
2850 nla_nest_end(skb, nla_results);
2851
2852 cfg80211_vendor_cmd_reply(skb);
2853
2854 } while (totalResults > 0);
2855 }
2856
2857 if (!pData->moreData) {
2858 spin_lock(&hdd_context_lock);
2859 context->response_status = 0;
2860 complete(&context->response_event);
2861 spin_unlock(&hdd_context_lock);
2862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302865 return;
2866fail:
2867 kfree_skb(skb);
2868 return;
2869}
2870
2871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2872 void *pMsg)
2873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302879 ENTER();
2880
2881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302882 hddLog(LOGE,
2883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302884 return;
2885 }
2886 if (!pMsg)
2887 {
2888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302889 return;
2890 }
2891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 if (pData->bss_found)
2893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2894 else
2895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2896
Dino Mycle6fb96c12014-06-10 11:52:40 +05302897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2899 NULL,
2900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302903
2904 if (!skb) {
2905 hddLog(VOS_TRACE_LEVEL_ERROR,
2906 FL("cfg80211_vendor_event_alloc failed"));
2907 return;
2908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2914
2915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2917 "Ssid (%s) "
2918 "Bssid (" MAC_ADDRESS_STR ") "
2919 "Channel (%u) "
2920 "Rssi (%d) "
2921 "RTT (%u) "
2922 "RTT_SD (%u) ",
2923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302924 pData->bssHotlist[i].ts,
2925 pData->bssHotlist[i].ssid,
2926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2927 pData->bssHotlist[i].channel,
2928 pData->bssHotlist[i].rssi,
2929 pData->bssHotlist[i].rtt,
2930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302931 }
2932
2933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2934 pData->requestId) ||
2935 nla_put_u32(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2939 goto fail;
2940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 struct nlattr *aps;
2943
2944 aps = nla_nest_start(skb,
2945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2946 if (!aps)
2947 goto fail;
2948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302950 struct nlattr *ap;
2951
2952 ap = nla_nest_start(skb, i + 1);
2953 if (!ap)
2954 goto fail;
2955
2956 if (nla_put_u64(skb,
2957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302959 nla_put(skb,
2960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302961 sizeof(pData->bssHotlist[i].ssid),
2962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302963 nla_put(skb,
2964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302965 sizeof(pData->bssHotlist[i].bssid),
2966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302967 nla_put_u32(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302970 nla_put_s32(skb,
2971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302973 nla_put_u32(skb,
2974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976 nla_put_u32(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979 goto fail;
2980
2981 nla_nest_end(skb, ap);
2982 }
2983 nla_nest_end(skb, aps);
2984
2985 if (nla_put_u8(skb,
2986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2987 pData->moreData))
2988 goto fail;
2989 }
2990
2991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993 return;
2994
2995fail:
2996 kfree_skb(skb);
2997 return;
2998
2999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303000
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303001/**
3002 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3003 * Handle an SSID hotlist match event
3004 * @ctx: HDD context registered with SME
3005 * @event: The SSID hotlist match event
3006 *
3007 * This function will take an SSID match event that was generated by
3008 * firmware and will convert it into a cfg80211 vendor event which is
3009 * sent to userspace.
3010 *
3011 * Return: none
3012 */
3013static void
3014wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3015 void *pMsg)
3016{
3017 hdd_context_t *hdd_ctx = ctx;
3018 struct sk_buff *skb;
3019 tANI_U32 i, index;
3020 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3021
3022 ENTER();
3023
3024 if (wlan_hdd_validate_context(hdd_ctx)) {
3025 hddLog(LOGE,
3026 FL("HDD context is not valid or response"));
3027 return;
3028 }
3029 if (!pMsg)
3030 {
3031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3032 return;
3033 }
3034
3035 if (pData->ssid_found) {
3036 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3037 hddLog(LOG1, "SSID hotlist found");
3038 } else {
3039 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3040 hddLog(LOG1, "SSID hotlist lost");
3041 }
3042
3043 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3045 NULL,
3046#endif
3047 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3048 index, GFP_KERNEL);
3049
3050 if (!skb) {
3051 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3052 return;
3053 }
3054 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3055 pData->requestId, pData->numHotlistSsid, pData->moreData);
3056
3057 for (i = 0; i < pData->numHotlistSsid; i++) {
3058 hddLog(LOG1, "[i=%d] Timestamp %llu "
3059 "Ssid: %s "
3060 "Bssid (" MAC_ADDRESS_STR ") "
3061 "Channel %u "
3062 "Rssi %d "
3063 "RTT %u "
3064 "RTT_SD %u",
3065 i,
3066 pData->ssidHotlist[i].ts,
3067 pData->ssidHotlist[i].ssid,
3068 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3069 pData->ssidHotlist[i].channel,
3070 pData->ssidHotlist[i].rssi,
3071 pData->ssidHotlist[i].rtt,
3072 pData->ssidHotlist[i].rtt_sd);
3073 }
3074
3075 if (nla_put_u32(skb,
3076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3077 pData->requestId) ||
3078 nla_put_u32(skb,
3079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3080 pData->numHotlistSsid)) {
3081 hddLog(LOGE, FL("put fail"));
3082 goto fail;
3083 }
3084
3085 if (pData->numHotlistSsid) {
3086 struct nlattr *aps;
3087 aps = nla_nest_start(skb,
3088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3089 if (!aps) {
3090 hddLog(LOGE, FL("nest fail"));
3091 goto fail;
3092 }
3093
3094 for (i = 0; i < pData->numHotlistSsid; i++) {
3095 struct nlattr *ap;
3096
3097 ap = nla_nest_start(skb, i);
3098 if (!ap) {
3099 hddLog(LOGE, FL("nest fail"));
3100 goto fail;
3101 }
3102
3103 if (nla_put_u64(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3105 pData->ssidHotlist[i].ts) ||
3106 nla_put(skb,
3107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3108 sizeof(pData->ssidHotlist[i].ssid),
3109 pData->ssidHotlist[i].ssid) ||
3110 nla_put(skb,
3111 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3112 sizeof(pData->ssidHotlist[i].bssid),
3113 pData->ssidHotlist[i].bssid) ||
3114 nla_put_u32(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3116 pData->ssidHotlist[i].channel) ||
3117 nla_put_s32(skb,
3118 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3119 pData->ssidHotlist[i].rssi) ||
3120 nla_put_u32(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3122 pData->ssidHotlist[i].rtt) ||
3123 nla_put_u32(skb,
3124 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3125 pData->ssidHotlist[i].rtt_sd)) {
3126 hddLog(LOGE, FL("put fail"));
3127 goto fail;
3128 }
3129 nla_nest_end(skb, ap);
3130 }
3131 nla_nest_end(skb, aps);
3132
3133 if (nla_put_u8(skb,
3134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3135 pData->moreData)) {
3136 hddLog(LOGE, FL("put fail"));
3137 goto fail;
3138 }
3139 }
3140
3141 cfg80211_vendor_event(skb, GFP_KERNEL);
3142 return;
3143
3144fail:
3145 kfree_skb(skb);
3146 return;
3147
3148}
3149
3150
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3152 void *pMsg)
3153{
3154 struct sk_buff *skb;
3155 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3156 tpSirWifiFullScanResultEvent pData =
3157 (tpSirWifiFullScanResultEvent) (pMsg);
3158
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303159 ENTER();
3160
3161 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303162 hddLog(LOGE,
3163 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303164 return;
3165 }
3166 if (!pMsg)
3167 {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303169 return;
3170 }
3171
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303172 /*
3173 * If the full scan result including IE data exceeds NL 4K size
3174 * limitation, drop that beacon/probe rsp frame.
3175 */
3176 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3177 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3178 return;
3179 }
3180
Dino Mycle6fb96c12014-06-10 11:52:40 +05303181 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3183 NULL,
3184#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3186 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3187 GFP_KERNEL);
3188
3189 if (!skb) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR,
3191 FL("cfg80211_vendor_event_alloc failed"));
3192 return;
3193 }
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3196 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3197 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3198 "Ssid (%s)"
3199 "Bssid (" MAC_ADDRESS_STR ")"
3200 "Channel (%u)"
3201 "Rssi (%d)"
3202 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303203 "RTT_SD (%u)"
3204 "Bcn Period %d"
3205 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303206 pData->ap.ts,
3207 pData->ap.ssid,
3208 MAC_ADDR_ARRAY(pData->ap.bssid),
3209 pData->ap.channel,
3210 pData->ap.rssi,
3211 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303212 pData->ap.rtt_sd,
3213 pData->ap.beaconPeriod,
3214 pData->ap.capability);
3215
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3217 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3218 pData->requestId) ||
3219 nla_put_u64(skb,
3220 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3221 pData->ap.ts) ||
3222 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3223 sizeof(pData->ap.ssid),
3224 pData->ap.ssid) ||
3225 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3226 WNI_CFG_BSSID_LEN,
3227 pData->ap.bssid) ||
3228 nla_put_u32(skb,
3229 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3230 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303231 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 pData->ap.rssi) ||
3233 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3234 pData->ap.rtt) ||
3235 nla_put_u32(skb,
3236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3237 pData->ap.rtt_sd) ||
3238 nla_put_u16(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3240 pData->ap.beaconPeriod) ||
3241 nla_put_u16(skb,
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3243 pData->ap.capability) ||
3244 nla_put_u32(skb,
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303246 pData->ieLength) ||
3247 nla_put_u8(skb,
3248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3249 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 {
3251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3252 goto nla_put_failure;
3253 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303254
3255 if (pData->ieLength) {
3256 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3257 pData->ieLength,
3258 pData->ie))
3259 {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3261 goto nla_put_failure;
3262 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303263 }
3264
3265 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267 return;
3268
3269nla_put_failure:
3270 kfree_skb(skb);
3271 return;
3272}
3273
3274static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3275 void *pMsg)
3276{
3277 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3278 struct sk_buff *skb = NULL;
3279 tpSirEXTScanResultsAvailableIndParams pData =
3280 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303282 ENTER();
3283
3284 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303285 hddLog(LOGE,
3286 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303287 return;
3288 }
3289 if (!pMsg)
3290 {
3291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303292 return;
3293 }
3294
3295 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3297 NULL,
3298#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3300 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3301 GFP_KERNEL);
3302
3303 if (!skb) {
3304 hddLog(VOS_TRACE_LEVEL_ERROR,
3305 FL("cfg80211_vendor_event_alloc failed"));
3306 return;
3307 }
3308
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3310 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3311 pData->numResultsAvailable);
3312 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3313 pData->requestId) ||
3314 nla_put_u32(skb,
3315 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3316 pData->numResultsAvailable)) {
3317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3318 goto nla_put_failure;
3319 }
3320
3321 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303322 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 return;
3324
3325nla_put_failure:
3326 kfree_skb(skb);
3327 return;
3328}
3329
3330static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3331{
3332 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3333 struct sk_buff *skb = NULL;
3334 tpSirEXTScanProgressIndParams pData =
3335 (tpSirEXTScanProgressIndParams) pMsg;
3336
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303337 ENTER();
3338
3339 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303340 hddLog(LOGE,
3341 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303342 return;
3343 }
3344 if (!pMsg)
3345 {
3346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303347 return;
3348 }
3349
3350 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3352 NULL,
3353#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3355 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3356 GFP_KERNEL);
3357
3358 if (!skb) {
3359 hddLog(VOS_TRACE_LEVEL_ERROR,
3360 FL("cfg80211_vendor_event_alloc failed"));
3361 return;
3362 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303364 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3365 pData->extScanEventType);
3366 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3367 pData->status);
3368
3369 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3370 pData->extScanEventType) ||
3371 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303372 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3373 pData->requestId) ||
3374 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303375 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3376 pData->status)) {
3377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3378 goto nla_put_failure;
3379 }
3380
3381 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303382 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303383 return;
3384
3385nla_put_failure:
3386 kfree_skb(skb);
3387 return;
3388}
3389
3390void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3391 void *pMsg)
3392{
3393 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303395 ENTER();
3396
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 return;
3399 }
3400
3401 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3402
3403
3404 switch(evType) {
3405 case SIR_HAL_EXTSCAN_START_RSP:
3406 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_STOP_RSP:
3410 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3411 break;
3412 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3413 /* There is no need to send this response to upper layer
3414 Just log the message */
3415 hddLog(VOS_TRACE_LEVEL_INFO,
3416 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3417 break;
3418 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3419 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3420 break;
3421
3422 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3423 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3424 break;
3425
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303426 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3427 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3428 break;
3429
3430 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3431 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3432 break;
3433
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303435 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303436 break;
3437 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3438 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3439 break;
3440 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3441 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3442 break;
3443 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3444 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3445 break;
3446 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3447 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3448 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303449 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3450 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3451 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3453 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3454 break;
3455 default:
3456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3457 break;
3458 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303459 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460}
3461
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303462static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3463 struct wireless_dev *wdev,
3464 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303465{
Dino Myclee8843b32014-07-04 14:21:45 +05303466 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303467 struct net_device *dev = wdev->netdev;
3468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3469 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3470 struct nlattr
3471 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3472 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303473 struct hdd_ext_scan_context *context;
3474 unsigned long rc;
3475 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303477 ENTER();
3478
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 status = wlan_hdd_validate_context(pHddCtx);
3480 if (0 != status)
3481 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 return -EINVAL;
3483 }
Dino Myclee8843b32014-07-04 14:21:45 +05303484 /* check the EXTScan Capability */
3485 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303486 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3487 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303488 {
3489 hddLog(VOS_TRACE_LEVEL_ERROR,
3490 FL("EXTScan not enabled/supported by Firmware"));
3491 return -EINVAL;
3492 }
3493
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3495 data, dataLen,
3496 wlan_hdd_extscan_config_policy)) {
3497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3498 return -EINVAL;
3499 }
3500
3501 /* Parse and fetch request Id */
3502 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3504 return -EINVAL;
3505 }
3506
Dino Myclee8843b32014-07-04 14:21:45 +05303507 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303509 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303510
Dino Myclee8843b32014-07-04 14:21:45 +05303511 reqMsg.sessionId = pAdapter->sessionId;
3512 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303514 vos_spin_lock_acquire(&hdd_context_lock);
3515 context = &pHddCtx->ext_scan_context;
3516 context->request_id = reqMsg.requestId;
3517 INIT_COMPLETION(context->response_event);
3518 vos_spin_lock_release(&hdd_context_lock);
3519
Dino Myclee8843b32014-07-04 14:21:45 +05303520 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 if (!HAL_STATUS_SUCCESS(status)) {
3522 hddLog(VOS_TRACE_LEVEL_ERROR,
3523 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524 return -EINVAL;
3525 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303526
3527 rc = wait_for_completion_timeout(&context->response_event,
3528 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3529 if (!rc) {
3530 hddLog(LOGE, FL("Target response timed out"));
3531 return -ETIMEDOUT;
3532 }
3533
3534 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3535 if (ret)
3536 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3537
3538 return ret;
3539
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303540 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 return 0;
3542}
3543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303544static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3545 struct wireless_dev *wdev,
3546 const void *data, int dataLen)
3547{
3548 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303550 vos_ssr_protect(__func__);
3551 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3552 vos_ssr_unprotect(__func__);
3553
3554 return ret;
3555}
3556
3557static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3558 struct wireless_dev *wdev,
3559 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560{
Dino Myclee8843b32014-07-04 14:21:45 +05303561 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 struct net_device *dev = wdev->netdev;
3563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3564 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3565 struct nlattr
3566 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3567 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303568 struct hdd_ext_scan_context *context;
3569 unsigned long rc;
3570 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303572 ENTER();
3573
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303574 if (VOS_FTM_MODE == hdd_get_conparam()) {
3575 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3576 return -EINVAL;
3577 }
3578
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 status = wlan_hdd_validate_context(pHddCtx);
3580 if (0 != status)
3581 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582 return -EINVAL;
3583 }
Dino Myclee8843b32014-07-04 14:21:45 +05303584 /* check the EXTScan Capability */
3585 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303586 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3587 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303588 {
3589 hddLog(VOS_TRACE_LEVEL_ERROR,
3590 FL("EXTScan not enabled/supported by Firmware"));
3591 return -EINVAL;
3592 }
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3595 data, dataLen,
3596 wlan_hdd_extscan_config_policy)) {
3597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3598 return -EINVAL;
3599 }
3600 /* Parse and fetch request Id */
3601 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3602 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3603 return -EINVAL;
3604 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605
Dino Myclee8843b32014-07-04 14:21:45 +05303606 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303607 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3608
Dino Myclee8843b32014-07-04 14:21:45 +05303609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303610
Dino Myclee8843b32014-07-04 14:21:45 +05303611 reqMsg.sessionId = pAdapter->sessionId;
3612 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613
3614 /* Parse and fetch flush parameter */
3615 if (!tb
3616 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3617 {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3619 goto failed;
3620 }
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3623
Dino Myclee8843b32014-07-04 14:21:45 +05303624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 spin_lock(&hdd_context_lock);
3627 context = &pHddCtx->ext_scan_context;
3628 context->request_id = reqMsg.requestId;
3629 context->ignore_cached_results = false;
3630 INIT_COMPLETION(context->response_event);
3631 spin_unlock(&hdd_context_lock);
3632
Dino Myclee8843b32014-07-04 14:21:45 +05303633 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634 if (!HAL_STATUS_SUCCESS(status)) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637 return -EINVAL;
3638 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303639
3640 rc = wait_for_completion_timeout(&context->response_event,
3641 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3642 if (!rc) {
3643 hddLog(LOGE, FL("Target response timed out"));
3644 retval = -ETIMEDOUT;
3645 spin_lock(&hdd_context_lock);
3646 context->ignore_cached_results = true;
3647 spin_unlock(&hdd_context_lock);
3648 } else {
3649 spin_lock(&hdd_context_lock);
3650 retval = context->response_status;
3651 spin_unlock(&hdd_context_lock);
3652 }
3653
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303654 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303655 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303656
3657failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 return -EINVAL;
3659}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303660static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3661 struct wireless_dev *wdev,
3662 const void *data, int dataLen)
3663{
3664 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303665
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303666 vos_ssr_protect(__func__);
3667 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3668 vos_ssr_unprotect(__func__);
3669
3670 return ret;
3671}
3672
3673static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303674 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303675 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676{
3677 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3678 struct net_device *dev = wdev->netdev;
3679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3680 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3681 struct nlattr
3682 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3683 struct nlattr
3684 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3685 struct nlattr *apTh;
3686 eHalStatus status;
3687 tANI_U8 i = 0;
3688 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303689 struct hdd_ext_scan_context *context;
3690 tANI_U32 request_id;
3691 unsigned long rc;
3692 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303694 ENTER();
3695
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303696 if (VOS_FTM_MODE == hdd_get_conparam()) {
3697 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3698 return -EINVAL;
3699 }
3700
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 status = wlan_hdd_validate_context(pHddCtx);
3702 if (0 != status)
3703 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 return -EINVAL;
3705 }
Dino Myclee8843b32014-07-04 14:21:45 +05303706 /* check the EXTScan Capability */
3707 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303708 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3709 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303710 {
3711 hddLog(VOS_TRACE_LEVEL_ERROR,
3712 FL("EXTScan not enabled/supported by Firmware"));
3713 return -EINVAL;
3714 }
3715
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3717 data, dataLen,
3718 wlan_hdd_extscan_config_policy)) {
3719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3720 return -EINVAL;
3721 }
3722
3723 /* Parse and fetch request Id */
3724 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3726 return -EINVAL;
3727 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303728 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3729 vos_mem_malloc(sizeof(*pReqMsg));
3730 if (!pReqMsg) {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3732 return -ENOMEM;
3733 }
3734
Dino Myclee8843b32014-07-04 14:21:45 +05303735
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 pReqMsg->requestId = nla_get_u32(
3737 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3738 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3739
3740 /* Parse and fetch number of APs */
3741 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3743 goto fail;
3744 }
3745
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303746 /* Parse and fetch lost ap sample size */
3747 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3748 hddLog(LOGE, FL("attr lost ap sample size failed"));
3749 goto fail;
3750 }
3751
3752 pReqMsg->lostBssidSampleSize = nla_get_u32(
3753 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3754 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3755
Dino Mycle6fb96c12014-06-10 11:52:40 +05303756 pReqMsg->sessionId = pAdapter->sessionId;
3757 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3758
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303759 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303762
3763 nla_for_each_nested(apTh,
3764 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3765 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3766 nla_data(apTh), nla_len(apTh),
3767 NULL)) {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3769 goto fail;
3770 }
3771
3772 /* Parse and fetch MAC address */
3773 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3775 goto fail;
3776 }
3777 memcpy(pReqMsg->ap[i].bssid, nla_data(
3778 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3779 sizeof(tSirMacAddr));
3780 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3781
3782 /* Parse and fetch low RSSI */
3783 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3785 goto fail;
3786 }
3787 pReqMsg->ap[i].low = nla_get_s32(
3788 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3789 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3790
3791 /* Parse and fetch high RSSI */
3792 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3794 goto fail;
3795 }
3796 pReqMsg->ap[i].high = nla_get_s32(
3797 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3798 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3799 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 i++;
3801 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303802
3803 context = &pHddCtx->ext_scan_context;
3804 spin_lock(&hdd_context_lock);
3805 INIT_COMPLETION(context->response_event);
3806 context->request_id = request_id = pReqMsg->requestId;
3807 spin_unlock(&hdd_context_lock);
3808
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3810 if (!HAL_STATUS_SUCCESS(status)) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR,
3812 FL("sme_SetBssHotlist failed(err=%d)"), status);
3813 vos_mem_free(pReqMsg);
3814 return -EINVAL;
3815 }
3816
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303817 /* request was sent -- wait for the response */
3818 rc = wait_for_completion_timeout(&context->response_event,
3819 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3820
3821 if (!rc) {
3822 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3823 retval = -ETIMEDOUT;
3824 } else {
3825 spin_lock(&hdd_context_lock);
3826 if (context->request_id == request_id)
3827 retval = context->response_status;
3828 else
3829 retval = -EINVAL;
3830 spin_unlock(&hdd_context_lock);
3831 }
3832
Dino Myclee8843b32014-07-04 14:21:45 +05303833 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303834 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303835 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836
3837fail:
3838 vos_mem_free(pReqMsg);
3839 return -EINVAL;
3840}
3841
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303842static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3843 struct wireless_dev *wdev,
3844 const void *data, int dataLen)
3845{
3846 int ret = 0;
3847
3848 vos_ssr_protect(__func__);
3849 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3850 dataLen);
3851 vos_ssr_unprotect(__func__);
3852
3853 return ret;
3854}
3855
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303856/*
3857 * define short names for the global vendor params
3858 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3859 */
3860#define PARAM_MAX \
3861QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3862#define PARAM_REQUEST_ID \
3863QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3864#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3865QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3866#define PARAMS_NUM_SSID \
3867QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3868#define THRESHOLD_PARAM \
3869QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3870#define PARAM_SSID \
3871QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3872#define PARAM_BAND \
3873QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3874#define PARAM_RSSI_LOW \
3875QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3876#define PARAM_RSSI_HIGH \
3877QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3878
3879/**
3880 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3881 * @wiphy: Pointer to wireless phy
3882 * @wdev: Pointer to wireless device
3883 * @data: Pointer to data
3884 * @data_len: Data length
3885 *
3886 * Return: 0 on success, negative errno on failure
3887 */
3888static int
3889__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3890 struct wireless_dev *wdev,
3891 const void *data,
3892 int data_len)
3893{
3894 tSirEXTScanSetSsidHotListReqParams *request;
3895 struct net_device *dev = wdev->netdev;
3896 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3897 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3898 struct nlattr *tb[PARAM_MAX + 1];
3899 struct nlattr *tb2[PARAM_MAX + 1];
3900 struct nlattr *ssids;
3901 struct hdd_ext_scan_context *context;
3902 uint32_t request_id;
3903 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3904 int ssid_len;
3905 eHalStatus status;
3906 int i, rem, retval;
3907 unsigned long rc;
3908
3909 ENTER();
3910
3911 if (VOS_FTM_MODE == hdd_get_conparam()) {
3912 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3913 return -EINVAL;
3914 }
3915
3916 retval = wlan_hdd_validate_context(hdd_ctx);
3917 if (0 != retval) {
3918 hddLog(LOGE, FL("HDD context is not valid"));
3919 return -EINVAL;
3920 }
3921
3922 /* check the EXTScan Capability */
3923 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303924 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3925 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303926 {
3927 hddLog(VOS_TRACE_LEVEL_ERROR,
3928 FL("EXTScan not enabled/supported by Firmware"));
3929 return -EINVAL;
3930 }
3931
3932 if (nla_parse(tb, PARAM_MAX,
3933 data, data_len,
3934 wlan_hdd_extscan_config_policy)) {
3935 hddLog(LOGE, FL("Invalid ATTR"));
3936 return -EINVAL;
3937 }
3938
3939 request = vos_mem_malloc(sizeof(*request));
3940 if (!request) {
3941 hddLog(LOGE, FL("vos_mem_malloc failed"));
3942 return -ENOMEM;
3943 }
3944
3945 /* Parse and fetch request Id */
3946 if (!tb[PARAM_REQUEST_ID]) {
3947 hddLog(LOGE, FL("attr request id failed"));
3948 goto fail;
3949 }
3950
3951 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3952 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3953
3954 /* Parse and fetch lost SSID sample size */
3955 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3956 hddLog(LOGE, FL("attr number of Ssid failed"));
3957 goto fail;
3958 }
3959 request->lost_ssid_sample_size =
3960 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3961 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3962 request->lost_ssid_sample_size);
3963
3964 /* Parse and fetch number of hotlist SSID */
3965 if (!tb[PARAMS_NUM_SSID]) {
3966 hddLog(LOGE, FL("attr number of Ssid failed"));
3967 goto fail;
3968 }
3969 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3970 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3971
3972 request->session_id = adapter->sessionId;
3973 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3974
3975 i = 0;
3976 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3977 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3978 hddLog(LOGE,
3979 FL("Too Many SSIDs, %d exceeds %d"),
3980 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3981 break;
3982 }
3983 if (nla_parse(tb2, PARAM_MAX,
3984 nla_data(ssids), nla_len(ssids),
3985 wlan_hdd_extscan_config_policy)) {
3986 hddLog(LOGE, FL("nla_parse failed"));
3987 goto fail;
3988 }
3989
3990 /* Parse and fetch SSID */
3991 if (!tb2[PARAM_SSID]) {
3992 hddLog(LOGE, FL("attr ssid failed"));
3993 goto fail;
3994 }
3995 nla_memcpy(ssid_string,
3996 tb2[PARAM_SSID],
3997 sizeof(ssid_string));
3998 hddLog(LOG1, FL("SSID %s"),
3999 ssid_string);
4000 ssid_len = strlen(ssid_string);
4001 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4002 request->ssid[i].ssid.length = ssid_len;
4003 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4004 hddLog(LOG1, FL("After copying SSID %s"),
4005 request->ssid[i].ssid.ssId);
4006 hddLog(LOG1, FL("After copying length: %d"),
4007 ssid_len);
4008
4009 /* Parse and fetch low RSSI */
4010 if (!tb2[PARAM_BAND]) {
4011 hddLog(LOGE, FL("attr band failed"));
4012 goto fail;
4013 }
4014 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4015 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4016
4017 /* Parse and fetch low RSSI */
4018 if (!tb2[PARAM_RSSI_LOW]) {
4019 hddLog(LOGE, FL("attr low RSSI failed"));
4020 goto fail;
4021 }
4022 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4023 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4024
4025 /* Parse and fetch high RSSI */
4026 if (!tb2[PARAM_RSSI_HIGH]) {
4027 hddLog(LOGE, FL("attr high RSSI failed"));
4028 goto fail;
4029 }
4030 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4031 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4032 i++;
4033 }
4034
4035 context = &hdd_ctx->ext_scan_context;
4036 spin_lock(&hdd_context_lock);
4037 INIT_COMPLETION(context->response_event);
4038 context->request_id = request_id = request->request_id;
4039 spin_unlock(&hdd_context_lock);
4040
4041 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4042 if (!HAL_STATUS_SUCCESS(status)) {
4043 hddLog(LOGE,
4044 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4045 goto fail;
4046 }
4047
4048 vos_mem_free(request);
4049
4050 /* request was sent -- wait for the response */
4051 rc = wait_for_completion_timeout(&context->response_event,
4052 msecs_to_jiffies
4053 (WLAN_WAIT_TIME_EXTSCAN));
4054 if (!rc) {
4055 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4056 retval = -ETIMEDOUT;
4057 } else {
4058 spin_lock(&hdd_context_lock);
4059 if (context->request_id == request_id)
4060 retval = context->response_status;
4061 else
4062 retval = -EINVAL;
4063 spin_unlock(&hdd_context_lock);
4064 }
4065
4066 return retval;
4067
4068fail:
4069 vos_mem_free(request);
4070 return -EINVAL;
4071}
4072
4073/*
4074 * done with short names for the global vendor params
4075 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4076 */
4077#undef PARAM_MAX
4078#undef PARAM_REQUEST_ID
4079#undef PARAMS_NUM_SSID
4080#undef THRESHOLD_PARAM
4081#undef PARAM_SSID
4082#undef PARAM_BAND
4083#undef PARAM_RSSI_LOW
4084#undef PARAM_RSSI_HIGH
4085
4086static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4087 struct wireless_dev *wdev,
4088 const void *data, int dataLen)
4089{
4090 int ret = 0;
4091
4092 vos_ssr_protect(__func__);
4093 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4094 dataLen);
4095 vos_ssr_unprotect(__func__);
4096
4097 return ret;
4098}
4099
4100static int
4101__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4102 struct wireless_dev *wdev,
4103 const void *data,
4104 int data_len)
4105{
4106 tSirEXTScanResetSsidHotlistReqParams request;
4107 struct net_device *dev = wdev->netdev;
4108 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4109 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4111 struct hdd_ext_scan_context *context;
4112 uint32_t request_id;
4113 eHalStatus status;
4114 int retval;
4115 unsigned long rc;
4116
4117 ENTER();
4118
4119 if (VOS_FTM_MODE == hdd_get_conparam()) {
4120 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4121 return -EINVAL;
4122 }
4123
4124 retval = wlan_hdd_validate_context(hdd_ctx);
4125 if (0 != retval) {
4126 hddLog(LOGE, FL("HDD context is not valid"));
4127 return -EINVAL;
4128 }
4129
4130 /* check the EXTScan Capability */
4131 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304132 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4133 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304134 {
4135 hddLog(LOGE,
4136 FL("EXTScan not enabled/supported by Firmware"));
4137 return -EINVAL;
4138 }
4139
4140 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4141 data, data_len,
4142 wlan_hdd_extscan_config_policy)) {
4143 hddLog(LOGE, FL("Invalid ATTR"));
4144 return -EINVAL;
4145 }
4146
4147 /* Parse and fetch request Id */
4148 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4149 hddLog(LOGE, FL("attr request id failed"));
4150 return -EINVAL;
4151 }
4152
4153 request.requestId = nla_get_u32(
4154 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4155 request.sessionId = adapter->sessionId;
4156 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4157 request.sessionId);
4158
4159 context = &hdd_ctx->ext_scan_context;
4160 spin_lock(&hdd_context_lock);
4161 INIT_COMPLETION(context->response_event);
4162 context->request_id = request_id = request.requestId;
4163 spin_unlock(&hdd_context_lock);
4164
4165 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4166 if (!HAL_STATUS_SUCCESS(status)) {
4167 hddLog(LOGE,
4168 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4169 return -EINVAL;
4170 }
4171
4172 /* request was sent -- wait for the response */
4173 rc = wait_for_completion_timeout(&context->response_event,
4174 msecs_to_jiffies
4175 (WLAN_WAIT_TIME_EXTSCAN));
4176 if (!rc) {
4177 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4178 retval = -ETIMEDOUT;
4179 } else {
4180 spin_lock(&hdd_context_lock);
4181 if (context->request_id == request_id)
4182 retval = context->response_status;
4183 else
4184 retval = -EINVAL;
4185 spin_unlock(&hdd_context_lock);
4186 }
4187
4188 return retval;
4189}
4190
4191static int
4192wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4193 struct wireless_dev *wdev,
4194 const void *data,
4195 int data_len)
4196{
4197 int ret;
4198
4199 vos_ssr_protect(__func__);
4200 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4201 data, data_len);
4202 vos_ssr_unprotect(__func__);
4203
4204 return ret;
4205}
4206
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304207static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304208 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304209 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210{
4211 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4212 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4213 tANI_U8 numChannels = 0;
4214 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304215 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 tWifiBand wifiBand;
4217 eHalStatus status;
4218 struct sk_buff *replySkb;
4219 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304220 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304221
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304222 ENTER();
4223
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 status = wlan_hdd_validate_context(pHddCtx);
4225 if (0 != status)
4226 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304227 return -EINVAL;
4228 }
Dino Myclee8843b32014-07-04 14:21:45 +05304229
Dino Mycle6fb96c12014-06-10 11:52:40 +05304230 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4231 data, dataLen,
4232 wlan_hdd_extscan_config_policy)) {
4233 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4234 return -EINVAL;
4235 }
4236
4237 /* Parse and fetch request Id */
4238 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4240 return -EINVAL;
4241 }
4242 requestId = nla_get_u32(
4243 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4244 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4245
4246 /* Parse and fetch wifi band */
4247 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4248 {
4249 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4250 return -EINVAL;
4251 }
4252 wifiBand = nla_get_u32(
4253 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4254 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4255
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304256 /* Parse and fetch max channels */
4257 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4258 {
4259 hddLog(LOGE, FL("attr max channels failed"));
4260 return -EINVAL;
4261 }
4262 maxChannels = nla_get_u32(
4263 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4264 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4265
Dino Mycle6fb96c12014-06-10 11:52:40 +05304266 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4267 wifiBand, ChannelList,
4268 &numChannels);
4269 if (eHAL_STATUS_SUCCESS != status) {
4270 hddLog(VOS_TRACE_LEVEL_ERROR,
4271 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4272 return -EINVAL;
4273 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304274
4275 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304277
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 for (i = 0; i < numChannels; i++)
4279 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4280
4281 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4282 sizeof(u32) * numChannels +
4283 NLMSG_HDRLEN);
4284
4285 if (!replySkb) {
4286 hddLog(VOS_TRACE_LEVEL_ERROR,
4287 FL("valid channels: buffer alloc fail"));
4288 return -EINVAL;
4289 }
4290 if (nla_put_u32(replySkb,
4291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4292 numChannels) ||
4293 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4294 sizeof(u32) * numChannels, ChannelList)) {
4295
4296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4297 kfree_skb(replySkb);
4298 return -EINVAL;
4299 }
4300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304301 ret = cfg80211_vendor_cmd_reply(replySkb);
4302
4303 EXIT();
4304 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305}
4306
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304307static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4308 struct wireless_dev *wdev,
4309 const void *data, int dataLen)
4310{
4311 int ret = 0;
4312
4313 vos_ssr_protect(__func__);
4314 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4315 dataLen);
4316 vos_ssr_unprotect(__func__);
4317
4318 return ret;
4319}
4320
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304321static int hdd_extscan_start_fill_bucket_channel_spec(
4322 hdd_context_t *pHddCtx,
4323 tpSirEXTScanStartReqParams pReqMsg,
4324 struct nlattr **tb)
4325{
4326 struct nlattr *bucket[
4327 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4328 struct nlattr *channel[
4329 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4330 struct nlattr *buckets;
4331 struct nlattr *channels;
4332 int rem1, rem2;
4333 eHalStatus status;
4334 tANI_U8 bktIndex, j, numChannels;
4335 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4336 tANI_U32 passive_max_chn_time, active_max_chn_time;
4337
4338 bktIndex = 0;
4339
4340 nla_for_each_nested(buckets,
4341 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4342 if (nla_parse(bucket,
4343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4344 nla_data(buckets), nla_len(buckets), NULL)) {
4345 hddLog(LOGE, FL("nla_parse failed"));
4346 return -EINVAL;
4347 }
4348
4349 /* Parse and fetch bucket spec */
4350 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4351 hddLog(LOGE, FL("attr bucket index failed"));
4352 return -EINVAL;
4353 }
4354 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4355 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4356 hddLog(LOG1, FL("Bucket spec Index %d"),
4357 pReqMsg->buckets[bktIndex].bucket);
4358
4359 /* Parse and fetch wifi band */
4360 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4361 hddLog(LOGE, FL("attr wifi band failed"));
4362 return -EINVAL;
4363 }
4364 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4365 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4366 hddLog(LOG1, FL("Wifi band %d"),
4367 pReqMsg->buckets[bktIndex].band);
4368
4369 /* Parse and fetch period */
4370 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4371 hddLog(LOGE, FL("attr period failed"));
4372 return -EINVAL;
4373 }
4374 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4375 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4376 hddLog(LOG1, FL("period %d"),
4377 pReqMsg->buckets[bktIndex].period);
4378
4379 /* Parse and fetch report events */
4380 if (!bucket[
4381 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4382 hddLog(LOGE, FL("attr report events failed"));
4383 return -EINVAL;
4384 }
4385 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4386 bucket[
4387 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4388 hddLog(LOG1, FL("report events %d"),
4389 pReqMsg->buckets[bktIndex].reportEvents);
4390
4391 /* Parse and fetch max period */
4392 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4393 hddLog(LOGE, FL("attr max period failed"));
4394 return -EINVAL;
4395 }
4396 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4397 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4398 hddLog(LOG1, FL("max period %u"),
4399 pReqMsg->buckets[bktIndex].max_period);
4400
4401 /* Parse and fetch exponent */
4402 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4403 hddLog(LOGE, FL("attr exponent failed"));
4404 return -EINVAL;
4405 }
4406 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4407 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4408 hddLog(LOG1, FL("exponent %u"),
4409 pReqMsg->buckets[bktIndex].exponent);
4410
4411 /* Parse and fetch step count */
4412 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4413 hddLog(LOGE, FL("attr step count failed"));
4414 return -EINVAL;
4415 }
4416 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4417 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4418 hddLog(LOG1, FL("Step count %u"),
4419 pReqMsg->buckets[bktIndex].step_count);
4420
4421 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4422 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4423
4424 /* Framework shall pass the channel list if the input WiFi band is
4425 * WIFI_BAND_UNSPECIFIED.
4426 * If the input WiFi band is specified (any value other than
4427 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4428 */
4429 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4430 numChannels = 0;
4431 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4432 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4433 pReqMsg->buckets[bktIndex].band,
4434 chanList, &numChannels);
4435 if (!HAL_STATUS_SUCCESS(status)) {
4436 hddLog(LOGE,
4437 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4438 status);
4439 return -EINVAL;
4440 }
4441
4442 pReqMsg->buckets[bktIndex].numChannels =
4443 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4444 hddLog(LOG1, FL("Num channels %d"),
4445 pReqMsg->buckets[bktIndex].numChannels);
4446
4447 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4448 j++) {
4449 pReqMsg->buckets[bktIndex].channels[j].channel =
4450 chanList[j];
4451 pReqMsg->buckets[bktIndex].channels[j].
4452 chnlClass = 0;
4453 if (CSR_IS_CHANNEL_DFS(
4454 vos_freq_to_chan(chanList[j]))) {
4455 pReqMsg->buckets[bktIndex].channels[j].
4456 passive = 1;
4457 pReqMsg->buckets[bktIndex].channels[j].
4458 dwellTimeMs = passive_max_chn_time;
4459 } else {
4460 pReqMsg->buckets[bktIndex].channels[j].
4461 passive = 0;
4462 pReqMsg->buckets[bktIndex].channels[j].
4463 dwellTimeMs = active_max_chn_time;
4464 }
4465
4466 hddLog(LOG1,
4467 "Channel %u Passive %u Dwell time %u ms",
4468 pReqMsg->buckets[bktIndex].channels[j].channel,
4469 pReqMsg->buckets[bktIndex].channels[j].passive,
4470 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4471 }
4472
4473 bktIndex++;
4474 continue;
4475 }
4476
4477 /* Parse and fetch number of channels */
4478 if (!bucket[
4479 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4480 hddLog(LOGE, FL("attr num channels failed"));
4481 return -EINVAL;
4482 }
4483
4484 pReqMsg->buckets[bktIndex].numChannels =
4485 nla_get_u32(bucket[
4486 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4487 hddLog(LOG1, FL("num channels %d"),
4488 pReqMsg->buckets[bktIndex].numChannels);
4489
4490 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4491 hddLog(LOGE, FL("attr channel spec failed"));
4492 return -EINVAL;
4493 }
4494
4495 j = 0;
4496 nla_for_each_nested(channels,
4497 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4498 if (nla_parse(channel,
4499 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4500 nla_data(channels), nla_len(channels),
4501 wlan_hdd_extscan_config_policy)) {
4502 hddLog(LOGE, FL("nla_parse failed"));
4503 return -EINVAL;
4504 }
4505
4506 /* Parse and fetch channel */
4507 if (!channel[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4509 hddLog(LOGE, FL("attr channel failed"));
4510 return -EINVAL;
4511 }
4512 pReqMsg->buckets[bktIndex].channels[j].channel =
4513 nla_get_u32(channel[
4514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4515 hddLog(LOG1, FL("channel %u"),
4516 pReqMsg->buckets[bktIndex].channels[j].channel);
4517
4518 /* Parse and fetch dwell time */
4519 if (!channel[
4520 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4521 hddLog(LOGE, FL("attr dwelltime failed"));
4522 return -EINVAL;
4523 }
4524 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4525 nla_get_u32(channel[
4526 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4527
4528 hddLog(LOG1, FL("Dwell time (%u ms)"),
4529 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4530
4531
4532 /* Parse and fetch channel spec passive */
4533 if (!channel[
4534 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4535 hddLog(LOGE,
4536 FL("attr channel spec passive failed"));
4537 return -EINVAL;
4538 }
4539 pReqMsg->buckets[bktIndex].channels[j].passive =
4540 nla_get_u8(channel[
4541 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4542 hddLog(LOG1, FL("Chnl spec passive %u"),
4543 pReqMsg->buckets[bktIndex].channels[j].passive);
4544
4545 j++;
4546 }
4547
4548 bktIndex++;
4549 }
4550
4551 return 0;
4552}
4553
4554
4555/*
4556 * define short names for the global vendor params
4557 * used by wlan_hdd_cfg80211_extscan_start()
4558 */
4559#define PARAM_MAX \
4560QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4561#define PARAM_REQUEST_ID \
4562QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4563#define PARAM_BASE_PERIOD \
4564QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4565#define PARAM_MAX_AP_PER_SCAN \
4566QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4567#define PARAM_RPT_THRHLD_PERCENT \
4568QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4569#define PARAM_RPT_THRHLD_NUM_SCANS \
4570QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4571#define PARAM_NUM_BUCKETS \
4572QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4573
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304574static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304576 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304577{
Dino Myclee8843b32014-07-04 14:21:45 +05304578 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304579 struct net_device *dev = wdev->netdev;
4580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4581 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4582 struct nlattr *tb[PARAM_MAX + 1];
4583 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304585 tANI_U32 request_id;
4586 struct hdd_ext_scan_context *context;
4587 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304589 ENTER();
4590
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304591 if (VOS_FTM_MODE == hdd_get_conparam()) {
4592 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4593 return -EINVAL;
4594 }
4595
Dino Mycle6fb96c12014-06-10 11:52:40 +05304596 status = wlan_hdd_validate_context(pHddCtx);
4597 if (0 != status)
4598 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 return -EINVAL;
4600 }
Dino Myclee8843b32014-07-04 14:21:45 +05304601 /* check the EXTScan Capability */
4602 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304603 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4604 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304605 {
4606 hddLog(VOS_TRACE_LEVEL_ERROR,
4607 FL("EXTScan not enabled/supported by Firmware"));
4608 return -EINVAL;
4609 }
4610
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304611 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 data, dataLen,
4613 wlan_hdd_extscan_config_policy)) {
4614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4615 return -EINVAL;
4616 }
4617
4618 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304619 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4621 return -EINVAL;
4622 }
4623
Dino Myclee8843b32014-07-04 14:21:45 +05304624 pReqMsg = (tpSirEXTScanStartReqParams)
4625 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304626 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4628 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629 }
4630
4631 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304632 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304633 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4634
4635 pReqMsg->sessionId = pAdapter->sessionId;
4636 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4637
4638 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304639 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304640 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4641 goto fail;
4642 }
4643 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304644 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4646 pReqMsg->basePeriod);
4647
4648 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304649 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4651 goto fail;
4652 }
4653 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304654 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4656 pReqMsg->maxAPperScan);
4657
4658 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304659 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4661 goto fail;
4662 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304663 pReqMsg->reportThresholdPercent = nla_get_u8(
4664 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304666 pReqMsg->reportThresholdPercent);
4667
4668 /* Parse and fetch report threshold num scans */
4669 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4670 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4671 goto fail;
4672 }
4673 pReqMsg->reportThresholdNumScans = nla_get_u8(
4674 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4675 hddLog(LOG1, FL("Report Threshold num scans %d"),
4676 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304677
4678 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304679 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4681 goto fail;
4682 }
4683 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304684 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304685 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4686 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4687 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4688 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4689 }
4690 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4691 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304692
Dino Mycle6fb96c12014-06-10 11:52:40 +05304693 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4695 goto fail;
4696 }
4697
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304698 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304699
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304700 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4701 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304702
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304703 context = &pHddCtx->ext_scan_context;
4704 spin_lock(&hdd_context_lock);
4705 INIT_COMPLETION(context->response_event);
4706 context->request_id = request_id = pReqMsg->requestId;
4707 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304708
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4710 if (!HAL_STATUS_SUCCESS(status)) {
4711 hddLog(VOS_TRACE_LEVEL_ERROR,
4712 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713 goto fail;
4714 }
4715
Srinivas Dasari91727c12016-03-23 17:59:06 +05304716 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4717
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 /* request was sent -- wait for the response */
4719 rc = wait_for_completion_timeout(&context->response_event,
4720 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4721
4722 if (!rc) {
4723 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4724 retval = -ETIMEDOUT;
4725 } else {
4726 spin_lock(&hdd_context_lock);
4727 if (context->request_id == request_id)
4728 retval = context->response_status;
4729 else
4730 retval = -EINVAL;
4731 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 }
4733
Dino Myclee8843b32014-07-04 14:21:45 +05304734 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304735 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304736 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304737
4738fail:
4739 vos_mem_free(pReqMsg);
4740 return -EINVAL;
4741}
4742
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304743/*
4744 * done with short names for the global vendor params
4745 * used by wlan_hdd_cfg80211_extscan_start()
4746 */
4747#undef PARAM_MAX
4748#undef PARAM_REQUEST_ID
4749#undef PARAM_BASE_PERIOD
4750#undef PARAMS_MAX_AP_PER_SCAN
4751#undef PARAMS_RPT_THRHLD_PERCENT
4752#undef PARAMS_RPT_THRHLD_NUM_SCANS
4753#undef PARAMS_NUM_BUCKETS
4754
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304755static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4756 struct wireless_dev *wdev,
4757 const void *data, int dataLen)
4758{
4759 int ret = 0;
4760
4761 vos_ssr_protect(__func__);
4762 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4763 vos_ssr_unprotect(__func__);
4764
4765 return ret;
4766}
4767
4768static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304769 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304770 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304771{
Dino Myclee8843b32014-07-04 14:21:45 +05304772 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304773 struct net_device *dev = wdev->netdev;
4774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4775 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4776 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4777 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304778 int retval;
4779 unsigned long rc;
4780 struct hdd_ext_scan_context *context;
4781 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304782
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304783 ENTER();
4784
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304785 if (VOS_FTM_MODE == hdd_get_conparam()) {
4786 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4787 return -EINVAL;
4788 }
4789
Dino Mycle6fb96c12014-06-10 11:52:40 +05304790 status = wlan_hdd_validate_context(pHddCtx);
4791 if (0 != status)
4792 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304793 return -EINVAL;
4794 }
Dino Myclee8843b32014-07-04 14:21:45 +05304795 /* check the EXTScan Capability */
4796 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304797 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4798 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304799 {
4800 hddLog(VOS_TRACE_LEVEL_ERROR,
4801 FL("EXTScan not enabled/supported by Firmware"));
4802 return -EINVAL;
4803 }
4804
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4806 data, dataLen,
4807 wlan_hdd_extscan_config_policy)) {
4808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4809 return -EINVAL;
4810 }
4811
4812 /* Parse and fetch request Id */
4813 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4815 return -EINVAL;
4816 }
4817
Dino Myclee8843b32014-07-04 14:21:45 +05304818 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821
Dino Myclee8843b32014-07-04 14:21:45 +05304822 reqMsg.sessionId = pAdapter->sessionId;
4823 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304825 context = &pHddCtx->ext_scan_context;
4826 spin_lock(&hdd_context_lock);
4827 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304828 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304829 spin_unlock(&hdd_context_lock);
4830
Dino Myclee8843b32014-07-04 14:21:45 +05304831 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 if (!HAL_STATUS_SUCCESS(status)) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR,
4834 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304835 return -EINVAL;
4836 }
4837
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304838 /* request was sent -- wait for the response */
4839 rc = wait_for_completion_timeout(&context->response_event,
4840 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4841
4842 if (!rc) {
4843 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4844 retval = -ETIMEDOUT;
4845 } else {
4846 spin_lock(&hdd_context_lock);
4847 if (context->request_id == request_id)
4848 retval = context->response_status;
4849 else
4850 retval = -EINVAL;
4851 spin_unlock(&hdd_context_lock);
4852 }
4853
4854 return retval;
4855
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304856 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304857 return 0;
4858}
4859
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304860static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4861 struct wireless_dev *wdev,
4862 const void *data, int dataLen)
4863{
4864 int ret = 0;
4865
4866 vos_ssr_protect(__func__);
4867 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4868 vos_ssr_unprotect(__func__);
4869
4870 return ret;
4871}
4872
4873static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304874 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304875 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304876{
Dino Myclee8843b32014-07-04 14:21:45 +05304877 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304878 struct net_device *dev = wdev->netdev;
4879 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4880 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4881 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4882 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304883 struct hdd_ext_scan_context *context;
4884 tANI_U32 request_id;
4885 unsigned long rc;
4886 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304888 ENTER();
4889
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304890 if (VOS_FTM_MODE == hdd_get_conparam()) {
4891 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4892 return -EINVAL;
4893 }
4894
Dino Mycle6fb96c12014-06-10 11:52:40 +05304895 status = wlan_hdd_validate_context(pHddCtx);
4896 if (0 != status)
4897 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304898 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899 return -EINVAL;
4900 }
Dino Myclee8843b32014-07-04 14:21:45 +05304901 /* check the EXTScan Capability */
4902 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304903 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4904 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304905 {
4906 hddLog(VOS_TRACE_LEVEL_ERROR,
4907 FL("EXTScan not enabled/supported by Firmware"));
4908 return -EINVAL;
4909 }
4910
Dino Mycle6fb96c12014-06-10 11:52:40 +05304911 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4912 data, dataLen,
4913 wlan_hdd_extscan_config_policy)) {
4914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4915 return -EINVAL;
4916 }
4917
4918 /* Parse and fetch request Id */
4919 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4921 return -EINVAL;
4922 }
4923
Dino Myclee8843b32014-07-04 14:21:45 +05304924 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304925 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304926 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304927
Dino Myclee8843b32014-07-04 14:21:45 +05304928 reqMsg.sessionId = pAdapter->sessionId;
4929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304931 context = &pHddCtx->ext_scan_context;
4932 spin_lock(&hdd_context_lock);
4933 INIT_COMPLETION(context->response_event);
4934 context->request_id = request_id = reqMsg.requestId;
4935 spin_unlock(&hdd_context_lock);
4936
Dino Myclee8843b32014-07-04 14:21:45 +05304937 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 if (!HAL_STATUS_SUCCESS(status)) {
4939 hddLog(VOS_TRACE_LEVEL_ERROR,
4940 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304941 return -EINVAL;
4942 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304943
4944 /* request was sent -- wait for the response */
4945 rc = wait_for_completion_timeout(&context->response_event,
4946 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4947 if (!rc) {
4948 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4949 retval = -ETIMEDOUT;
4950 } else {
4951 spin_lock(&hdd_context_lock);
4952 if (context->request_id == request_id)
4953 retval = context->response_status;
4954 else
4955 retval = -EINVAL;
4956 spin_unlock(&hdd_context_lock);
4957 }
4958
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304959 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304960 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304961}
4962
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304963static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4964 struct wireless_dev *wdev,
4965 const void *data, int dataLen)
4966{
4967 int ret = 0;
4968
4969 vos_ssr_protect(__func__);
4970 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4971 vos_ssr_unprotect(__func__);
4972
4973 return ret;
4974}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304975#endif /* WLAN_FEATURE_EXTSCAN */
4976
Atul Mittal115287b2014-07-08 13:26:33 +05304977/*EXT TDLS*/
4978static const struct nla_policy
4979wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4980{
4981 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4984 {.type = NLA_S32 },
4985 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4986 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4987
4988};
4989
4990static const struct nla_policy
4991wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4992{
4993 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4994
4995};
4996
4997static const struct nla_policy
4998wlan_hdd_tdls_config_state_change_policy[
4999 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5000{
5001 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5002 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5003 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305004 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5005 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5006 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305007
5008};
5009
5010static const struct nla_policy
5011wlan_hdd_tdls_config_get_status_policy[
5012 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5013{
5014 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5016 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305017 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5018 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5019 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305020
5021};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305022
5023static const struct nla_policy
5024wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5025{
5026 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5027};
5028
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305029static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305030 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305031 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305032 int data_len)
5033{
5034
5035 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5036 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5037
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305038 ENTER();
5039
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305040 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305041 return -EINVAL;
5042 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305043 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305044 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305045 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305046 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305047 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305048 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305049 return -ENOTSUPP;
5050 }
5051
5052 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5053 data, data_len, wlan_hdd_mac_config)) {
5054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5055 return -EINVAL;
5056 }
5057
5058 /* Parse and fetch mac address */
5059 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5061 return -EINVAL;
5062 }
5063
5064 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5065 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5066 VOS_MAC_ADDR_LAST_3_BYTES);
5067
Siddharth Bhal76972212014-10-15 16:22:51 +05305068 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5069
5070 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305071 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5072 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305073 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5074 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5075 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5076 {
5077 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5078 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5079 VOS_MAC_ADDRESS_LEN);
5080 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305081 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305082
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305083 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5084 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305086 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305087 return 0;
5088}
5089
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305090static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5091 struct wireless_dev *wdev,
5092 const void *data,
5093 int data_len)
5094{
5095 int ret = 0;
5096
5097 vos_ssr_protect(__func__);
5098 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5099 vos_ssr_unprotect(__func__);
5100
5101 return ret;
5102}
5103
5104static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305105 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305106 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305107 int data_len)
5108{
5109 u8 peer[6] = {0};
5110 struct net_device *dev = wdev->netdev;
5111 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5112 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5113 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5114 eHalStatus ret;
5115 tANI_S32 state;
5116 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305117 tANI_S32 global_operating_class = 0;
5118 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305119 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305120 int retVal;
5121
5122 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305123
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305124 if (!pAdapter) {
5125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5126 return -EINVAL;
5127 }
5128
Atul Mittal115287b2014-07-08 13:26:33 +05305129 ret = wlan_hdd_validate_context(pHddCtx);
5130 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305132 return -EINVAL;
5133 }
5134 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305136 return -ENOTSUPP;
5137 }
5138 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5139 data, data_len,
5140 wlan_hdd_tdls_config_get_status_policy)) {
5141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5142 return -EINVAL;
5143 }
5144
5145 /* Parse and fetch mac address */
5146 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5148 return -EINVAL;
5149 }
5150
5151 memcpy(peer, nla_data(
5152 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5153 sizeof(peer));
5154 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5155
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305156 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305157
Atul Mittal115287b2014-07-08 13:26:33 +05305158 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305159 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305160 NLMSG_HDRLEN);
5161
5162 if (!skb) {
5163 hddLog(VOS_TRACE_LEVEL_ERROR,
5164 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5165 return -EINVAL;
5166 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305167 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305168 reason,
5169 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305170 global_operating_class,
5171 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305172 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305173 if (nla_put_s32(skb,
5174 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5175 state) ||
5176 nla_put_s32(skb,
5177 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5178 reason) ||
5179 nla_put_s32(skb,
5180 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5181 global_operating_class) ||
5182 nla_put_s32(skb,
5183 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5184 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305185
5186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5187 goto nla_put_failure;
5188 }
5189
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305190 retVal = cfg80211_vendor_cmd_reply(skb);
5191 EXIT();
5192 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305193
5194nla_put_failure:
5195 kfree_skb(skb);
5196 return -EINVAL;
5197}
5198
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305199static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5200 struct wireless_dev *wdev,
5201 const void *data,
5202 int data_len)
5203{
5204 int ret = 0;
5205
5206 vos_ssr_protect(__func__);
5207 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5208 vos_ssr_unprotect(__func__);
5209
5210 return ret;
5211}
5212
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305213static int wlan_hdd_cfg80211_exttdls_callback(
5214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5215 const tANI_U8* mac,
5216#else
5217 tANI_U8* mac,
5218#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305219 tANI_S32 state,
5220 tANI_S32 reason,
5221 void *ctx)
5222{
5223 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305224 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305225 tANI_S32 global_operating_class = 0;
5226 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305227 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305228
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305229 ENTER();
5230
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305231 if (!pAdapter) {
5232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5233 return -EINVAL;
5234 }
5235
5236 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305237 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305239 return -EINVAL;
5240 }
5241
5242 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305244 return -ENOTSUPP;
5245 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305246 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5247#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5248 NULL,
5249#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305250 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5251 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5252 GFP_KERNEL);
5253
5254 if (!skb) {
5255 hddLog(VOS_TRACE_LEVEL_ERROR,
5256 FL("cfg80211_vendor_event_alloc failed"));
5257 return -EINVAL;
5258 }
5259 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305260 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5261 reason,
5262 state,
5263 global_operating_class,
5264 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305265 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5266 MAC_ADDR_ARRAY(mac));
5267
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305268 if (nla_put(skb,
5269 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5270 VOS_MAC_ADDR_SIZE, mac) ||
5271 nla_put_s32(skb,
5272 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5273 state) ||
5274 nla_put_s32(skb,
5275 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5276 reason) ||
5277 nla_put_s32(skb,
5278 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5279 channel) ||
5280 nla_put_s32(skb,
5281 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5282 global_operating_class)
5283 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5285 goto nla_put_failure;
5286 }
5287
5288 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305289 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305290 return (0);
5291
5292nla_put_failure:
5293 kfree_skb(skb);
5294 return -EINVAL;
5295}
5296
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305297static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305298 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305299 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305300 int data_len)
5301{
5302 u8 peer[6] = {0};
5303 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305304 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5305 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5306 eHalStatus status;
5307 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305308 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305309 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305310
5311 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305312
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305313 if (!dev) {
5314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5315 return -EINVAL;
5316 }
5317
5318 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5319 if (!pAdapter) {
5320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5321 return -EINVAL;
5322 }
5323
Atul Mittal115287b2014-07-08 13:26:33 +05305324 status = wlan_hdd_validate_context(pHddCtx);
5325 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305327 return -EINVAL;
5328 }
5329 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305331 return -ENOTSUPP;
5332 }
5333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5334 data, data_len,
5335 wlan_hdd_tdls_config_enable_policy)) {
5336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5337 return -EINVAL;
5338 }
5339
5340 /* Parse and fetch mac address */
5341 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5343 return -EINVAL;
5344 }
5345
5346 memcpy(peer, nla_data(
5347 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5348 sizeof(peer));
5349 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5350
5351 /* Parse and fetch channel */
5352 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5354 return -EINVAL;
5355 }
5356 pReqMsg.channel = nla_get_s32(
5357 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5358 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5359
5360 /* Parse and fetch global operating class */
5361 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5363 return -EINVAL;
5364 }
5365 pReqMsg.global_operating_class = nla_get_s32(
5366 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5368 pReqMsg.global_operating_class);
5369
5370 /* Parse and fetch latency ms */
5371 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5373 return -EINVAL;
5374 }
5375 pReqMsg.max_latency_ms = nla_get_s32(
5376 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5377 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5378 pReqMsg.max_latency_ms);
5379
5380 /* Parse and fetch required bandwidth kbps */
5381 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5383 return -EINVAL;
5384 }
5385
5386 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5387 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5388 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5389 pReqMsg.min_bandwidth_kbps);
5390
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305391 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305392 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305393 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305394 wlan_hdd_cfg80211_exttdls_callback);
5395
5396 EXIT();
5397 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305398}
5399
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305400static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5401 struct wireless_dev *wdev,
5402 const void *data,
5403 int data_len)
5404{
5405 int ret = 0;
5406
5407 vos_ssr_protect(__func__);
5408 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5409 vos_ssr_unprotect(__func__);
5410
5411 return ret;
5412}
5413
5414static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305415 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305416 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305417 int data_len)
5418{
5419 u8 peer[6] = {0};
5420 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305421 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5422 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5423 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305424 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305425 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305426
5427 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305428
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305429 if (!dev) {
5430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5431 return -EINVAL;
5432 }
5433
5434 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5435 if (!pAdapter) {
5436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5437 return -EINVAL;
5438 }
5439
Atul Mittal115287b2014-07-08 13:26:33 +05305440 status = wlan_hdd_validate_context(pHddCtx);
5441 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305443 return -EINVAL;
5444 }
5445 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305447 return -ENOTSUPP;
5448 }
5449 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5450 data, data_len,
5451 wlan_hdd_tdls_config_disable_policy)) {
5452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5453 return -EINVAL;
5454 }
5455 /* Parse and fetch mac address */
5456 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5458 return -EINVAL;
5459 }
5460
5461 memcpy(peer, nla_data(
5462 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5463 sizeof(peer));
5464 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305466 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5467
5468 EXIT();
5469 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305470}
5471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305472static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5473 struct wireless_dev *wdev,
5474 const void *data,
5475 int data_len)
5476{
5477 int ret = 0;
5478
5479 vos_ssr_protect(__func__);
5480 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5481 vos_ssr_unprotect(__func__);
5482
5483 return ret;
5484}
5485
Dasari Srinivas7875a302014-09-26 17:50:57 +05305486static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305487__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305488 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305489 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305490{
5491 struct net_device *dev = wdev->netdev;
5492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5493 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5494 struct sk_buff *skb = NULL;
5495 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305496 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305498 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305499
5500 ret = wlan_hdd_validate_context(pHddCtx);
5501 if (0 != ret)
5502 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305503 return ret;
5504 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305505 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5506 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5507 fset |= WIFI_FEATURE_INFRA;
5508 }
5509
5510 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5511 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5512 fset |= WIFI_FEATURE_INFRA_5G;
5513 }
5514
5515#ifdef WLAN_FEATURE_P2P
5516 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5517 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5518 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5519 fset |= WIFI_FEATURE_P2P;
5520 }
5521#endif
5522
5523 /* Soft-AP is supported currently by default */
5524 fset |= WIFI_FEATURE_SOFT_AP;
5525
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305526 /* HOTSPOT is a supplicant feature, enable it by default */
5527 fset |= WIFI_FEATURE_HOTSPOT;
5528
Dasari Srinivas7875a302014-09-26 17:50:57 +05305529#ifdef WLAN_FEATURE_EXTSCAN
5530 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305531 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5532 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5533 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305534 fset |= WIFI_FEATURE_EXTSCAN;
5535 }
5536#endif
5537
Dasari Srinivas7875a302014-09-26 17:50:57 +05305538 if (sme_IsFeatureSupportedByFW(NAN)) {
5539 hddLog(LOG1, FL("NAN is supported by firmware"));
5540 fset |= WIFI_FEATURE_NAN;
5541 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305542
5543 /* D2D RTT is not supported currently by default */
5544 if (sme_IsFeatureSupportedByFW(RTT)) {
5545 hddLog(LOG1, FL("RTT is supported by firmware"));
5546 fset |= WIFI_FEATURE_D2AP_RTT;
5547 }
5548
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305549 if (sme_IsFeatureSupportedByFW(RTT3)) {
5550 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5551 fset |= WIFI_FEATURE_RTT3;
5552 }
5553
Dasari Srinivas7875a302014-09-26 17:50:57 +05305554#ifdef FEATURE_WLAN_BATCH_SCAN
5555 if (fset & WIFI_FEATURE_EXTSCAN) {
5556 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5557 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5558 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5559 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5560 fset |= WIFI_FEATURE_BATCH_SCAN;
5561 }
5562#endif
5563
5564#ifdef FEATURE_WLAN_SCAN_PNO
5565 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5566 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5567 hddLog(LOG1, FL("PNO is supported by firmware"));
5568 fset |= WIFI_FEATURE_PNO;
5569 }
5570#endif
5571
5572 /* STA+STA is supported currently by default */
5573 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5574
5575#ifdef FEATURE_WLAN_TDLS
5576 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5577 sme_IsFeatureSupportedByFW(TDLS)) {
5578 hddLog(LOG1, FL("TDLS is supported by firmware"));
5579 fset |= WIFI_FEATURE_TDLS;
5580 }
5581
5582 /* TDLS_OFFCHANNEL is not supported currently by default */
5583#endif
5584
5585#ifdef WLAN_AP_STA_CONCURRENCY
5586 /* AP+STA concurrency is supported currently by default */
5587 fset |= WIFI_FEATURE_AP_STA;
5588#endif
5589
Mukul Sharma5add0532015-08-17 15:57:47 +05305590#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5591 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5592 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5593#endif
5594
Dasari Srinivas7875a302014-09-26 17:50:57 +05305595 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5596 NLMSG_HDRLEN);
5597
5598 if (!skb) {
5599 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5600 return -EINVAL;
5601 }
5602 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5603
5604 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5605 hddLog(LOGE, FL("nla put fail"));
5606 goto nla_put_failure;
5607 }
5608
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305609 ret = cfg80211_vendor_cmd_reply(skb);
5610 EXIT();
5611 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305612
5613nla_put_failure:
5614 kfree_skb(skb);
5615 return -EINVAL;
5616}
5617
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305618static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305619wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5620 struct wireless_dev *wdev,
5621 const void *data, int data_len)
5622{
5623 int ret = 0;
5624
5625 vos_ssr_protect(__func__);
5626 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5627 vos_ssr_unprotect(__func__);
5628
5629 return ret;
5630}
5631
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305632
5633static const struct
5634nla_policy
5635qca_wlan_vendor_wifi_logger_get_ring_data_policy
5636[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5637 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5638 = {.type = NLA_U32 },
5639};
5640
5641static int
5642 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5643 struct wireless_dev *wdev,
5644 const void *data,
5645 int data_len)
5646{
5647 int ret;
5648 VOS_STATUS status;
5649 uint32_t ring_id;
5650 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5651 struct nlattr *tb
5652 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5653
5654 ENTER();
5655
5656 ret = wlan_hdd_validate_context(hdd_ctx);
5657 if (0 != ret) {
5658 return ret;
5659 }
5660
5661 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5662 data, data_len,
5663 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5664 hddLog(LOGE, FL("Invalid attribute"));
5665 return -EINVAL;
5666 }
5667
5668 /* Parse and fetch ring id */
5669 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5670 hddLog(LOGE, FL("attr ATTR failed"));
5671 return -EINVAL;
5672 }
5673
5674 ring_id = nla_get_u32(
5675 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5676
5677 hddLog(LOG1, FL("Bug report triggered by framework"));
5678
5679 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5680 WLAN_LOG_INDICATOR_FRAMEWORK,
5681 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305682 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305683 );
5684 if (VOS_STATUS_SUCCESS != status) {
5685 hddLog(LOGE, FL("Failed to trigger bug report"));
5686
5687 return -EINVAL;
5688 }
5689
5690 return 0;
5691
5692
5693}
5694
5695
5696static int
5697 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5698 struct wireless_dev *wdev,
5699 const void *data,
5700 int data_len)
5701{
5702 int ret = 0;
5703
5704 vos_ssr_protect(__func__);
5705 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5706 wdev, data, data_len);
5707 vos_ssr_unprotect(__func__);
5708
5709 return ret;
5710
5711}
5712
5713
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305714static int
5715__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305716 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305717 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305718{
5719 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5720 uint8_t i, feature_sets, max_feature_sets;
5721 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5722 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305723 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5724 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305725
5726 ENTER();
5727
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305728 ret = wlan_hdd_validate_context(pHddCtx);
5729 if (0 != ret)
5730 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305731 return ret;
5732 }
5733
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305734 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5735 data, data_len, NULL)) {
5736 hddLog(LOGE, FL("Invalid ATTR"));
5737 return -EINVAL;
5738 }
5739
5740 /* Parse and fetch max feature set */
5741 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5742 hddLog(LOGE, FL("Attr max feature set size failed"));
5743 return -EINVAL;
5744 }
5745 max_feature_sets = nla_get_u32(
5746 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5747 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5748
5749 /* Fill feature combination matrix */
5750 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305751 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5752 WIFI_FEATURE_P2P;
5753
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305754 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5755 WIFI_FEATURE_SOFT_AP;
5756
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305757 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5758 WIFI_FEATURE_SOFT_AP;
5759
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305760 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5761 WIFI_FEATURE_SOFT_AP |
5762 WIFI_FEATURE_P2P;
5763
5764 /* Add more feature combinations here */
5765
5766 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5767 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5768 hddLog(LOG1, "Feature set matrix");
5769 for (i = 0; i < feature_sets; i++)
5770 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5771
5772 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5773 sizeof(u32) * feature_sets +
5774 NLMSG_HDRLEN);
5775
5776 if (reply_skb) {
5777 if (nla_put_u32(reply_skb,
5778 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5779 feature_sets) ||
5780 nla_put(reply_skb,
5781 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5782 sizeof(u32) * feature_sets, feature_set_matrix)) {
5783 hddLog(LOGE, FL("nla put fail"));
5784 kfree_skb(reply_skb);
5785 return -EINVAL;
5786 }
5787
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305788 ret = cfg80211_vendor_cmd_reply(reply_skb);
5789 EXIT();
5790 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305791 }
5792 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5793 return -ENOMEM;
5794
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305795}
5796
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305797static int
5798wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5799 struct wireless_dev *wdev,
5800 const void *data, int data_len)
5801{
5802 int ret = 0;
5803
5804 vos_ssr_protect(__func__);
5805 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5806 data_len);
5807 vos_ssr_unprotect(__func__);
5808
5809 return ret;
5810}
5811
c_manjeecfd1efb2015-09-25 19:32:34 +05305812
5813static int
5814__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5815 struct wireless_dev *wdev,
5816 const void *data, int data_len)
5817{
5818 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5819 int ret;
5820 ENTER();
5821
5822 ret = wlan_hdd_validate_context(pHddCtx);
5823 if (0 != ret)
5824 {
5825 return ret;
5826 }
5827
5828 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5829 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5830 {
5831 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5832 return -EINVAL;
5833 }
5834 /*call common API for FW mem dump req*/
5835 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5836
Abhishek Singhc783fa72015-12-09 18:07:34 +05305837 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305838 {
5839 /*indicate to userspace the status of fw mem dump */
5840 wlan_indicate_mem_dump_complete(true);
5841 }
5842 else
5843 {
5844 /*else send failure to userspace */
5845 wlan_indicate_mem_dump_complete(false);
5846 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305847 EXIT();
5848 return ret;
5849}
5850
5851/**
5852 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5853 * @wiphy: pointer to wireless wiphy structure.
5854 * @wdev: pointer to wireless_dev structure.
5855 * @data: Pointer to the NL data.
5856 * @data_len:Length of @data
5857 *
5858 * This is called when wlan driver needs to get the firmware memory dump
5859 * via vendor specific command.
5860 *
5861 * Return: 0 on success, error number otherwise.
5862 */
5863
5864static int
5865wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5866 struct wireless_dev *wdev,
5867 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305868{
5869 int ret = 0;
5870 vos_ssr_protect(__func__);
5871 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5872 data_len);
5873 vos_ssr_unprotect(__func__);
5874 return ret;
5875}
c_manjeecfd1efb2015-09-25 19:32:34 +05305876
Sushant Kaushik8e644982015-09-23 12:18:54 +05305877static const struct
5878nla_policy
5879qca_wlan_vendor_wifi_logger_start_policy
5880[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5881 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5882 = {.type = NLA_U32 },
5883 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5884 = {.type = NLA_U32 },
5885 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5886 = {.type = NLA_U32 },
5887};
5888
5889/**
5890 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5891 * or disable the collection of packet statistics from the firmware
5892 * @wiphy: WIPHY structure pointer
5893 * @wdev: Wireless device structure pointer
5894 * @data: Pointer to the data received
5895 * @data_len: Length of the data received
5896 *
5897 * This function is used to enable or disable the collection of packet
5898 * statistics from the firmware
5899 *
5900 * Return: 0 on success and errno on failure
5901 */
5902static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5903 struct wireless_dev *wdev,
5904 const void *data,
5905 int data_len)
5906{
5907 eHalStatus status;
5908 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5909 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5910 tAniWifiStartLog start_log;
5911
5912 status = wlan_hdd_validate_context(hdd_ctx);
5913 if (0 != status) {
5914 return -EINVAL;
5915 }
5916
5917 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5918 data, data_len,
5919 qca_wlan_vendor_wifi_logger_start_policy)) {
5920 hddLog(LOGE, FL("Invalid attribute"));
5921 return -EINVAL;
5922 }
5923
5924 /* Parse and fetch ring id */
5925 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5926 hddLog(LOGE, FL("attr ATTR failed"));
5927 return -EINVAL;
5928 }
5929 start_log.ringId = nla_get_u32(
5930 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5931 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5932
5933 /* Parse and fetch verbose level */
5934 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5935 hddLog(LOGE, FL("attr verbose_level failed"));
5936 return -EINVAL;
5937 }
5938 start_log.verboseLevel = nla_get_u32(
5939 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5940 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5941
5942 /* Parse and fetch flag */
5943 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5944 hddLog(LOGE, FL("attr flag failed"));
5945 return -EINVAL;
5946 }
5947 start_log.flag = nla_get_u32(
5948 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5949 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5950
5951 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305952 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5953 !vos_isPktStatsEnabled()))
5954
Sushant Kaushik8e644982015-09-23 12:18:54 +05305955 {
5956 hddLog(LOGE, FL("per pkt stats not enabled"));
5957 return -EINVAL;
5958 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305959
Sushant Kaushik33200572015-08-05 16:46:20 +05305960 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305961 return 0;
5962}
5963
5964/**
5965 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5966 * or disable the collection of packet statistics from the firmware
5967 * @wiphy: WIPHY structure pointer
5968 * @wdev: Wireless device structure pointer
5969 * @data: Pointer to the data received
5970 * @data_len: Length of the data received
5971 *
5972 * This function is used to enable or disable the collection of packet
5973 * statistics from the firmware
5974 *
5975 * Return: 0 on success and errno on failure
5976 */
5977static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5978 struct wireless_dev *wdev,
5979 const void *data,
5980 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305981{
5982 int ret = 0;
5983
5984 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305985
5986 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5987 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305988 vos_ssr_unprotect(__func__);
5989
5990 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305991}
5992
5993
Agarwal Ashish738843c2014-09-25 12:27:56 +05305994static const struct nla_policy
5995wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5996 +1] =
5997{
5998 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5999};
6000
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306001static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306002 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306003 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306004 int data_len)
6005{
6006 struct net_device *dev = wdev->netdev;
6007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6008 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6009 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6010 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6011 eHalStatus status;
6012 u32 dfsFlag = 0;
6013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306014 ENTER();
6015
Agarwal Ashish738843c2014-09-25 12:27:56 +05306016 status = wlan_hdd_validate_context(pHddCtx);
6017 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306018 return -EINVAL;
6019 }
6020 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6021 data, data_len,
6022 wlan_hdd_set_no_dfs_flag_config_policy)) {
6023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6024 return -EINVAL;
6025 }
6026
6027 /* Parse and fetch required bandwidth kbps */
6028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6030 return -EINVAL;
6031 }
6032
6033 dfsFlag = nla_get_u32(
6034 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6035 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6036 dfsFlag);
6037
6038 pHddCtx->disable_dfs_flag = dfsFlag;
6039
6040 sme_disable_dfs_channel(hHal, dfsFlag);
6041 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306042
6043 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306044 return 0;
6045}
Atul Mittal115287b2014-07-08 13:26:33 +05306046
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306047static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6048 struct wireless_dev *wdev,
6049 const void *data,
6050 int data_len)
6051{
6052 int ret = 0;
6053
6054 vos_ssr_protect(__func__);
6055 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6056 vos_ssr_unprotect(__func__);
6057
6058 return ret;
6059
6060}
6061
Mukul Sharma2a271632014-10-13 14:59:01 +05306062const struct
6063nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6064{
6065 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6066 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6067};
6068
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306069static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306070 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306071{
6072
6073 u8 bssid[6] = {0};
6074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6075 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6076 eHalStatus status = eHAL_STATUS_SUCCESS;
6077 v_U32_t isFwrRoamEnabled = FALSE;
6078 int ret;
6079
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306080 ENTER();
6081
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306082 ret = wlan_hdd_validate_context(pHddCtx);
6083 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306084 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306085 }
6086
6087 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6088 data, data_len,
6089 qca_wlan_vendor_attr);
6090 if (ret){
6091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6092 return -EINVAL;
6093 }
6094
6095 /* Parse and fetch Enable flag */
6096 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6098 return -EINVAL;
6099 }
6100
6101 isFwrRoamEnabled = nla_get_u32(
6102 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6103
6104 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6105
6106 /* Parse and fetch bssid */
6107 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6109 return -EINVAL;
6110 }
6111
6112 memcpy(bssid, nla_data(
6113 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6114 sizeof(bssid));
6115 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6116
6117 //Update roaming
6118 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306119 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306120 return status;
6121}
6122
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306123static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6124 struct wireless_dev *wdev, const void *data, int data_len)
6125{
6126 int ret = 0;
6127
6128 vos_ssr_protect(__func__);
6129 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6130 vos_ssr_unprotect(__func__);
6131
6132 return ret;
6133}
6134
Sushant Kaushik847890c2015-09-28 16:05:17 +05306135static const struct
6136nla_policy
6137qca_wlan_vendor_get_wifi_info_policy[
6138 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6139 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6140 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6141};
6142
6143
6144/**
6145 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6146 * @wiphy: pointer to wireless wiphy structure.
6147 * @wdev: pointer to wireless_dev structure.
6148 * @data: Pointer to the data to be passed via vendor interface
6149 * @data_len:Length of the data to be passed
6150 *
6151 * This is called when wlan driver needs to send wifi driver related info
6152 * (driver/fw version) to the user space application upon request.
6153 *
6154 * Return: Return the Success or Failure code.
6155 */
6156static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6157 struct wireless_dev *wdev,
6158 const void *data, int data_len)
6159{
6160 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6161 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6162 tSirVersionString version;
6163 uint32 version_len;
6164 uint8 attr;
6165 int status;
6166 struct sk_buff *reply_skb = NULL;
6167
6168 if (VOS_FTM_MODE == hdd_get_conparam()) {
6169 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6170 return -EINVAL;
6171 }
6172
6173 status = wlan_hdd_validate_context(hdd_ctx);
6174 if (0 != status) {
6175 hddLog(LOGE, FL("HDD context is not valid"));
6176 return -EINVAL;
6177 }
6178
6179 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6180 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6181 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6182 return -EINVAL;
6183 }
6184
6185 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6186 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6187 QWLAN_VERSIONSTR);
6188 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6189 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6190 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6191 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6192 hdd_ctx->fw_Version);
6193 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6194 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6195 } else {
6196 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6197 return -EINVAL;
6198 }
6199
6200 version_len = strlen(version);
6201 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6202 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6203 if (!reply_skb) {
6204 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6205 return -ENOMEM;
6206 }
6207
6208 if (nla_put(reply_skb, attr, version_len, version)) {
6209 hddLog(LOGE, FL("nla put fail"));
6210 kfree_skb(reply_skb);
6211 return -EINVAL;
6212 }
6213
6214 return cfg80211_vendor_cmd_reply(reply_skb);
6215}
6216
6217/**
6218 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6219 * @wiphy: pointer to wireless wiphy structure.
6220 * @wdev: pointer to wireless_dev structure.
6221 * @data: Pointer to the data to be passed via vendor interface
6222 * @data_len:Length of the data to be passed
6223 * @data_len: Length of the data received
6224 *
6225 * This function is used to enable or disable the collection of packet
6226 * statistics from the firmware
6227 *
6228 * Return: 0 on success and errno on failure
6229 */
6230
6231static int
6232wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6233 struct wireless_dev *wdev,
6234 const void *data, int data_len)
6235
6236
6237{
6238 int ret = 0;
6239
6240 vos_ssr_protect(__func__);
6241 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6242 wdev, data, data_len);
6243 vos_ssr_unprotect(__func__);
6244
6245 return ret;
6246}
6247
6248
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306249/*
6250 * define short names for the global vendor params
6251 * used by __wlan_hdd_cfg80211_monitor_rssi()
6252 */
6253#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6254#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6255#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6256#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6257#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6258
6259/**---------------------------------------------------------------------------
6260
6261 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6262 monitor start is completed successfully.
6263
6264 \return - None
6265
6266 --------------------------------------------------------------------------*/
6267void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6268{
6269 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6270
6271 if (NULL == pHddCtx)
6272 {
6273 hddLog(VOS_TRACE_LEVEL_ERROR,
6274 "%s: HDD context is NULL",__func__);
6275 return;
6276 }
6277
6278 if (VOS_STATUS_SUCCESS == status)
6279 {
6280 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6281 }
6282 else
6283 {
6284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6285 }
6286
6287 return;
6288}
6289
6290/**---------------------------------------------------------------------------
6291
6292 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6293 stop is completed successfully.
6294
6295 \return - None
6296
6297 --------------------------------------------------------------------------*/
6298void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6299{
6300 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6301
6302 if (NULL == pHddCtx)
6303 {
6304 hddLog(VOS_TRACE_LEVEL_ERROR,
6305 "%s: HDD context is NULL",__func__);
6306 return;
6307 }
6308
6309 if (VOS_STATUS_SUCCESS == status)
6310 {
6311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6312 }
6313 else
6314 {
6315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6316 }
6317
6318 return;
6319}
6320
6321/**
6322 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6323 * @wiphy: Pointer to wireless phy
6324 * @wdev: Pointer to wireless device
6325 * @data: Pointer to data
6326 * @data_len: Data length
6327 *
6328 * Return: 0 on success, negative errno on failure
6329 */
6330
6331static int
6332__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6333 struct wireless_dev *wdev,
6334 const void *data,
6335 int data_len)
6336{
6337 struct net_device *dev = wdev->netdev;
6338 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6339 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6340 hdd_station_ctx_t *pHddStaCtx;
6341 struct nlattr *tb[PARAM_MAX + 1];
6342 tpSirRssiMonitorReq pReq;
6343 eHalStatus status;
6344 int ret;
6345 uint32_t control;
6346 static const struct nla_policy policy[PARAM_MAX + 1] = {
6347 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6348 [PARAM_CONTROL] = { .type = NLA_U32 },
6349 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6350 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6351 };
6352
6353 ENTER();
6354
6355 ret = wlan_hdd_validate_context(hdd_ctx);
6356 if (0 != ret) {
6357 return -EINVAL;
6358 }
6359
6360 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6361 hddLog(LOGE, FL("Not in Connected state!"));
6362 return -ENOTSUPP;
6363 }
6364
6365 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6366 hddLog(LOGE, FL("Invalid ATTR"));
6367 return -EINVAL;
6368 }
6369
6370 if (!tb[PARAM_REQUEST_ID]) {
6371 hddLog(LOGE, FL("attr request id failed"));
6372 return -EINVAL;
6373 }
6374
6375 if (!tb[PARAM_CONTROL]) {
6376 hddLog(LOGE, FL("attr control failed"));
6377 return -EINVAL;
6378 }
6379
6380 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6381
6382 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6383 if(NULL == pReq)
6384 {
6385 hddLog(LOGE,
6386 FL("vos_mem_alloc failed "));
6387 return eHAL_STATUS_FAILED_ALLOC;
6388 }
6389 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6390
6391 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6392 pReq->sessionId = pAdapter->sessionId;
6393 pReq->rssiMonitorCbContext = hdd_ctx;
6394 control = nla_get_u32(tb[PARAM_CONTROL]);
6395 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6396
6397 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6398 pReq->requestId, pReq->sessionId, control);
6399
6400 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6401 if (!tb[PARAM_MIN_RSSI]) {
6402 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306403 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306404 }
6405
6406 if (!tb[PARAM_MAX_RSSI]) {
6407 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306408 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306409 }
6410
6411 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6412 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6413 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6414
6415 if (!(pReq->minRssi < pReq->maxRssi)) {
6416 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6417 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306418 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306419 }
6420 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6421 pReq->minRssi, pReq->maxRssi);
6422 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6423
6424 }
6425 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6426 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6427 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6428 }
6429 else {
6430 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306431 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306432 }
6433
6434 if (!HAL_STATUS_SUCCESS(status)) {
6435 hddLog(LOGE,
6436 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306437 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306438 }
6439
6440 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306441fail:
6442 vos_mem_free(pReq);
6443 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306444}
6445
6446/*
6447 * done with short names for the global vendor params
6448 * used by __wlan_hdd_cfg80211_monitor_rssi()
6449 */
6450#undef PARAM_MAX
6451#undef PARAM_CONTROL
6452#undef PARAM_REQUEST_ID
6453#undef PARAM_MAX_RSSI
6454#undef PARAM_MIN_RSSI
6455
6456/**
6457 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6458 * @wiphy: wiphy structure pointer
6459 * @wdev: Wireless device structure pointer
6460 * @data: Pointer to the data received
6461 * @data_len: Length of @data
6462 *
6463 * Return: 0 on success; errno on failure
6464 */
6465static int
6466wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6467 const void *data, int data_len)
6468{
6469 int ret;
6470
6471 vos_ssr_protect(__func__);
6472 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6473 vos_ssr_unprotect(__func__);
6474
6475 return ret;
6476}
6477
6478/**
6479 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6480 * @hddctx: HDD context
6481 * @data: rssi breached event data
6482 *
6483 * This function reads the rssi breached event %data and fill in the skb with
6484 * NL attributes and send up the NL event.
6485 * This callback execute in atomic context and must not invoke any
6486 * blocking calls.
6487 *
6488 * Return: none
6489 */
6490void hdd_rssi_threshold_breached_cb(void *hddctx,
6491 struct rssi_breach_event *data)
6492{
6493 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6494 int status;
6495 struct sk_buff *skb;
6496
6497 ENTER();
6498 status = wlan_hdd_validate_context(pHddCtx);
6499
6500 if (0 != status) {
6501 return;
6502 }
6503
6504 if (!data) {
6505 hddLog(LOGE, FL("data is null"));
6506 return;
6507 }
6508
6509 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6510#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6511 NULL,
6512#endif
6513 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6514 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6515 GFP_KERNEL);
6516
6517 if (!skb) {
6518 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6519 return;
6520 }
6521
6522 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6523 data->request_id, data->curr_rssi);
6524 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6525 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6526
6527 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6528 data->request_id) ||
6529 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6530 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6531 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6532 data->curr_rssi)) {
6533 hddLog(LOGE, FL("nla put fail"));
6534 goto fail;
6535 }
6536
6537 cfg80211_vendor_event(skb, GFP_KERNEL);
6538 return;
6539
6540fail:
6541 kfree_skb(skb);
6542 return;
6543}
6544
6545
6546
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306547/**
6548 * __wlan_hdd_cfg80211_setband() - set band
6549 * @wiphy: Pointer to wireless phy
6550 * @wdev: Pointer to wireless device
6551 * @data: Pointer to data
6552 * @data_len: Data length
6553 *
6554 * Return: 0 on success, negative errno on failure
6555 */
6556static int
6557__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6558 struct wireless_dev *wdev,
6559 const void *data,
6560 int data_len)
6561{
6562 struct net_device *dev = wdev->netdev;
6563 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6564 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6565 int ret;
6566 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6567 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6568
6569 ENTER();
6570
6571 ret = wlan_hdd_validate_context(hdd_ctx);
6572 if (0 != ret) {
6573 hddLog(LOGE, FL("HDD context is not valid"));
6574 return ret;
6575 }
6576
6577 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6578 policy)) {
6579 hddLog(LOGE, FL("Invalid ATTR"));
6580 return -EINVAL;
6581 }
6582
6583 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6584 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6585 return -EINVAL;
6586 }
6587
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306588 hdd_ctx->isSetBandByNL = TRUE;
6589 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306590 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306591 hdd_ctx->isSetBandByNL = FALSE;
6592
6593 EXIT();
6594 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306595}
6596
6597/**
6598 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6599 * @wiphy: wiphy structure pointer
6600 * @wdev: Wireless device structure pointer
6601 * @data: Pointer to the data received
6602 * @data_len: Length of @data
6603 *
6604 * Return: 0 on success; errno on failure
6605 */
6606static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6607 struct wireless_dev *wdev,
6608 const void *data,
6609 int data_len)
6610{
6611 int ret = 0;
6612
6613 vos_ssr_protect(__func__);
6614 ret = __wlan_hdd_cfg80211_setband(wiphy,
6615 wdev, data, data_len);
6616 vos_ssr_unprotect(__func__);
6617
6618 return ret;
6619}
6620
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306621#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6622/**
6623 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6624 * @hdd_ctx: HDD context
6625 * @request_id: [input] request id
6626 * @pattern_id: [output] pattern id
6627 *
6628 * This function loops through request id to pattern id array
6629 * if the slot is available, store the request id and return pattern id
6630 * if entry exists, return the pattern id
6631 *
6632 * Return: 0 on success and errno on failure
6633 */
6634static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6635 uint32_t request_id,
6636 uint8_t *pattern_id)
6637{
6638 uint32_t i;
6639
6640 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6641 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6642 {
6643 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6644 {
6645 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6646 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6647 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6648 return 0;
6649 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6650 request_id) {
6651 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6652 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6653 return 0;
6654 }
6655 }
6656 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6657 return -EINVAL;
6658}
6659
6660/**
6661 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6662 * @hdd_ctx: HDD context
6663 * @request_id: [input] request id
6664 * @pattern_id: [output] pattern id
6665 *
6666 * This function loops through request id to pattern id array
6667 * reset request id to 0 (slot available again) and
6668 * return pattern id
6669 *
6670 * Return: 0 on success and errno on failure
6671 */
6672static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6673 uint32_t request_id,
6674 uint8_t *pattern_id)
6675{
6676 uint32_t i;
6677
6678 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6679 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6680 {
6681 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6682 {
6683 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6684 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6685 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6686 return 0;
6687 }
6688 }
6689 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6690 return -EINVAL;
6691}
6692
6693
6694/*
6695 * define short names for the global vendor params
6696 * used by __wlan_hdd_cfg80211_offloaded_packets()
6697 */
6698#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6699#define PARAM_REQUEST_ID \
6700 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6701#define PARAM_CONTROL \
6702 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6703#define PARAM_IP_PACKET \
6704 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6705#define PARAM_SRC_MAC_ADDR \
6706 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6707#define PARAM_DST_MAC_ADDR \
6708 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6709#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6710
6711/**
6712 * wlan_hdd_add_tx_ptrn() - add tx pattern
6713 * @adapter: adapter pointer
6714 * @hdd_ctx: hdd context
6715 * @tb: nl attributes
6716 *
6717 * This function reads the NL attributes and forms a AddTxPtrn message
6718 * posts it to SME.
6719 *
6720 */
6721static int
6722wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6723 struct nlattr **tb)
6724{
6725 struct sSirAddPeriodicTxPtrn *add_req;
6726 eHalStatus status;
6727 uint32_t request_id, ret, len;
6728 uint8_t pattern_id = 0;
6729 v_MACADDR_t dst_addr;
6730 uint16_t eth_type = htons(ETH_P_IP);
6731
6732 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6733 {
6734 hddLog(LOGE, FL("Not in Connected state!"));
6735 return -ENOTSUPP;
6736 }
6737
6738 add_req = vos_mem_malloc(sizeof(*add_req));
6739 if (!add_req)
6740 {
6741 hddLog(LOGE, FL("memory allocation failed"));
6742 return -ENOMEM;
6743 }
6744
6745 /* Parse and fetch request Id */
6746 if (!tb[PARAM_REQUEST_ID])
6747 {
6748 hddLog(LOGE, FL("attr request id failed"));
6749 goto fail;
6750 }
6751
6752 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6753 hddLog(LOG1, FL("Request Id: %u"), request_id);
6754 if (request_id == 0)
6755 {
6756 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306757 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306758 }
6759
6760 if (!tb[PARAM_PERIOD])
6761 {
6762 hddLog(LOGE, FL("attr period failed"));
6763 goto fail;
6764 }
6765 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6766 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6767 if (add_req->usPtrnIntervalMs == 0)
6768 {
6769 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6770 goto fail;
6771 }
6772
6773 if (!tb[PARAM_SRC_MAC_ADDR])
6774 {
6775 hddLog(LOGE, FL("attr source mac address failed"));
6776 goto fail;
6777 }
6778 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6779 VOS_MAC_ADDR_SIZE);
6780 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6781 MAC_ADDR_ARRAY(add_req->macAddress));
6782
6783 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6784 VOS_MAC_ADDR_SIZE))
6785 {
6786 hddLog(LOGE,
6787 FL("input src mac address and connected ap bssid are different"));
6788 goto fail;
6789 }
6790
6791 if (!tb[PARAM_DST_MAC_ADDR])
6792 {
6793 hddLog(LOGE, FL("attr dst mac address failed"));
6794 goto fail;
6795 }
6796 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6797 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6798 MAC_ADDR_ARRAY(dst_addr.bytes));
6799
6800 if (!tb[PARAM_IP_PACKET])
6801 {
6802 hddLog(LOGE, FL("attr ip packet failed"));
6803 goto fail;
6804 }
6805 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6806 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6807
6808 if (add_req->ucPtrnSize < 0 ||
6809 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6810 HDD_ETH_HEADER_LEN))
6811 {
6812 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6813 add_req->ucPtrnSize);
6814 goto fail;
6815 }
6816
6817 len = 0;
6818 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6819 len += VOS_MAC_ADDR_SIZE;
6820 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6821 VOS_MAC_ADDR_SIZE);
6822 len += VOS_MAC_ADDR_SIZE;
6823 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6824 len += 2;
6825
6826 /*
6827 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6828 * ------------------------------------------------------------
6829 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6830 * ------------------------------------------------------------
6831 */
6832 vos_mem_copy(&add_req->ucPattern[len],
6833 nla_data(tb[PARAM_IP_PACKET]),
6834 add_req->ucPtrnSize);
6835 add_req->ucPtrnSize += len;
6836
6837 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6838 add_req->ucPattern, add_req->ucPtrnSize);
6839
6840 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6841 if (ret)
6842 {
6843 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6844 goto fail;
6845 }
6846 add_req->ucPtrnId = pattern_id;
6847 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6848
6849 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6850 if (!HAL_STATUS_SUCCESS(status))
6851 {
6852 hddLog(LOGE,
6853 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6854 goto fail;
6855 }
6856
6857 EXIT();
6858 vos_mem_free(add_req);
6859 return 0;
6860
6861fail:
6862 vos_mem_free(add_req);
6863 return -EINVAL;
6864}
6865
6866/**
6867 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6868 * @adapter: adapter pointer
6869 * @hdd_ctx: hdd context
6870 * @tb: nl attributes
6871 *
6872 * This function reads the NL attributes and forms a DelTxPtrn message
6873 * posts it to SME.
6874 *
6875 */
6876static int
6877wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6878 struct nlattr **tb)
6879{
6880 struct sSirDelPeriodicTxPtrn *del_req;
6881 eHalStatus status;
6882 uint32_t request_id, ret;
6883 uint8_t pattern_id = 0;
6884
6885 /* Parse and fetch request Id */
6886 if (!tb[PARAM_REQUEST_ID])
6887 {
6888 hddLog(LOGE, FL("attr request id failed"));
6889 return -EINVAL;
6890 }
6891 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6892 if (request_id == 0)
6893 {
6894 hddLog(LOGE, FL("request_id cannot be zero"));
6895 return -EINVAL;
6896 }
6897
6898 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6899 if (ret)
6900 {
6901 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6902 return -EINVAL;
6903 }
6904
6905 del_req = vos_mem_malloc(sizeof(*del_req));
6906 if (!del_req)
6907 {
6908 hddLog(LOGE, FL("memory allocation failed"));
6909 return -ENOMEM;
6910 }
6911
6912 vos_mem_set(del_req, sizeof(*del_req), 0);
6913 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6914 VOS_MAC_ADDR_SIZE);
6915 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6916 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6917 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6918 request_id, pattern_id, del_req->ucPatternIdBitmap);
6919
6920 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6921 if (!HAL_STATUS_SUCCESS(status))
6922 {
6923 hddLog(LOGE,
6924 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6925 goto fail;
6926 }
6927
6928 EXIT();
6929 vos_mem_free(del_req);
6930 return 0;
6931
6932fail:
6933 vos_mem_free(del_req);
6934 return -EINVAL;
6935}
6936
6937
6938/**
6939 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6940 * @wiphy: Pointer to wireless phy
6941 * @wdev: Pointer to wireless device
6942 * @data: Pointer to data
6943 * @data_len: Data length
6944 *
6945 * Return: 0 on success, negative errno on failure
6946 */
6947static int
6948__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6949 struct wireless_dev *wdev,
6950 const void *data,
6951 int data_len)
6952{
6953 struct net_device *dev = wdev->netdev;
6954 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6955 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6956 struct nlattr *tb[PARAM_MAX + 1];
6957 uint8_t control;
6958 int ret;
6959 static const struct nla_policy policy[PARAM_MAX + 1] =
6960 {
6961 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6962 [PARAM_CONTROL] = { .type = NLA_U32 },
6963 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6964 .len = VOS_MAC_ADDR_SIZE },
6965 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6966 .len = VOS_MAC_ADDR_SIZE },
6967 [PARAM_PERIOD] = { .type = NLA_U32 },
6968 };
6969
6970 ENTER();
6971
6972 ret = wlan_hdd_validate_context(hdd_ctx);
6973 if (0 != ret)
6974 {
6975 hddLog(LOGE, FL("HDD context is not valid"));
6976 return ret;
6977 }
6978
6979 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6980 {
6981 hddLog(LOGE,
6982 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6983 return -ENOTSUPP;
6984 }
6985
6986 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6987 {
6988 hddLog(LOGE, FL("Invalid ATTR"));
6989 return -EINVAL;
6990 }
6991
6992 if (!tb[PARAM_CONTROL])
6993 {
6994 hddLog(LOGE, FL("attr control failed"));
6995 return -EINVAL;
6996 }
6997 control = nla_get_u32(tb[PARAM_CONTROL]);
6998 hddLog(LOG1, FL("Control: %d"), control);
6999
7000 if (control == WLAN_START_OFFLOADED_PACKETS)
7001 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7002 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7003 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7004 else
7005 {
7006 hddLog(LOGE, FL("Invalid control: %d"), control);
7007 return -EINVAL;
7008 }
7009}
7010
7011/*
7012 * done with short names for the global vendor params
7013 * used by __wlan_hdd_cfg80211_offloaded_packets()
7014 */
7015#undef PARAM_MAX
7016#undef PARAM_REQUEST_ID
7017#undef PARAM_CONTROL
7018#undef PARAM_IP_PACKET
7019#undef PARAM_SRC_MAC_ADDR
7020#undef PARAM_DST_MAC_ADDR
7021#undef PARAM_PERIOD
7022
7023/**
7024 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7025 * @wiphy: wiphy structure pointer
7026 * @wdev: Wireless device structure pointer
7027 * @data: Pointer to the data received
7028 * @data_len: Length of @data
7029 *
7030 * Return: 0 on success; errno on failure
7031 */
7032static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7033 struct wireless_dev *wdev,
7034 const void *data,
7035 int data_len)
7036{
7037 int ret = 0;
7038
7039 vos_ssr_protect(__func__);
7040 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7041 wdev, data, data_len);
7042 vos_ssr_unprotect(__func__);
7043
7044 return ret;
7045}
7046#endif
7047
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307048static const struct
7049nla_policy
7050qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7051 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7052};
7053
7054/**
7055 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7056 * get link properties like nss, rate flags and operating frequency for
7057 * the connection with the given peer.
7058 * @wiphy: WIPHY structure pointer
7059 * @wdev: Wireless device structure pointer
7060 * @data: Pointer to the data received
7061 * @data_len: Length of the data received
7062 *
7063 * This function return the above link properties on success.
7064 *
7065 * Return: 0 on success and errno on failure
7066 */
7067static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7068 struct wireless_dev *wdev,
7069 const void *data,
7070 int data_len)
7071{
7072 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7073 struct net_device *dev = wdev->netdev;
7074 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7075 hdd_station_ctx_t *hdd_sta_ctx;
7076 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7077 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7078 uint32_t sta_id;
7079 struct sk_buff *reply_skb;
7080 uint32_t rate_flags = 0;
7081 uint8_t nss;
7082 uint8_t final_rate_flags = 0;
7083 uint32_t freq;
7084 v_CONTEXT_t pVosContext = NULL;
7085 ptSapContext pSapCtx = NULL;
7086
7087 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7089 return -EINVAL;
7090 }
7091
7092 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7093 qca_wlan_vendor_attr_policy)) {
7094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7095 return -EINVAL;
7096 }
7097
7098 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7099 hddLog(VOS_TRACE_LEVEL_ERROR,
7100 FL("Attribute peerMac not provided for mode=%d"),
7101 adapter->device_mode);
7102 return -EINVAL;
7103 }
7104
7105 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7106 sizeof(peer_mac));
7107 hddLog(VOS_TRACE_LEVEL_INFO,
7108 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7109 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7110
7111 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7112 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7113 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7114 if ((hdd_sta_ctx->conn_info.connState !=
7115 eConnectionState_Associated) ||
7116 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7117 VOS_MAC_ADDRESS_LEN)) {
7118 hddLog(VOS_TRACE_LEVEL_ERROR,
7119 FL("Not Associated to mac "MAC_ADDRESS_STR),
7120 MAC_ADDR_ARRAY(peer_mac));
7121 return -EINVAL;
7122 }
7123
7124 nss = 1; //pronto supports only one spatial stream
7125 freq = vos_chan_to_freq(
7126 hdd_sta_ctx->conn_info.operationChannel);
7127 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7128
7129 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7130 adapter->device_mode == WLAN_HDD_SOFTAP) {
7131
7132 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7133 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7134 if(pSapCtx == NULL){
7135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7136 FL("psapCtx is NULL"));
7137 return -ENOENT;
7138 }
7139
7140
7141 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7142 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7143 !vos_is_macaddr_broadcast(
7144 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7145 vos_mem_compare(
7146 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7147 peer_mac, VOS_MAC_ADDRESS_LEN))
7148 break;
7149 }
7150
7151 if (WLAN_MAX_STA_COUNT == sta_id) {
7152 hddLog(VOS_TRACE_LEVEL_ERROR,
7153 FL("No active peer with mac="MAC_ADDRESS_STR),
7154 MAC_ADDR_ARRAY(peer_mac));
7155 return -EINVAL;
7156 }
7157
7158 nss = 1; //pronto supports only one spatial stream
7159 freq = vos_chan_to_freq(
7160 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7161 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7162 } else {
7163 hddLog(VOS_TRACE_LEVEL_ERROR,
7164 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7165 MAC_ADDR_ARRAY(peer_mac));
7166 return -EINVAL;
7167 }
7168
7169 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7170 if (rate_flags & eHAL_TX_RATE_VHT80) {
7171 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7172 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7173 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7174 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7175 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7176 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7177 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7178 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7179 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7180 if (rate_flags & eHAL_TX_RATE_HT40)
7181 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7182 }
7183
7184 if (rate_flags & eHAL_TX_RATE_SGI) {
7185 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7186 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7187 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7188 }
7189 }
7190
7191 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7192 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7193
7194 if (NULL == reply_skb) {
7195 hddLog(VOS_TRACE_LEVEL_ERROR,
7196 FL("getLinkProperties: skb alloc failed"));
7197 return -EINVAL;
7198 }
7199
7200 if (nla_put_u8(reply_skb,
7201 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7202 nss) ||
7203 nla_put_u8(reply_skb,
7204 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7205 final_rate_flags) ||
7206 nla_put_u32(reply_skb,
7207 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7208 freq)) {
7209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7210 kfree_skb(reply_skb);
7211 return -EINVAL;
7212 }
7213
7214 return cfg80211_vendor_cmd_reply(reply_skb);
7215}
7216
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307217#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7218#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7219#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7220#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307221#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7222 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307223
7224/**
7225 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7226 * vendor command
7227 *
7228 * @wiphy: wiphy device pointer
7229 * @wdev: wireless device pointer
7230 * @data: Vendor command data buffer
7231 * @data_len: Buffer length
7232 *
7233 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7234 *
7235 * Return: EOK or other error codes.
7236 */
7237
7238static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7239 struct wireless_dev *wdev,
7240 const void *data,
7241 int data_len)
7242{
7243 struct net_device *dev = wdev->netdev;
7244 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7245 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7246 hdd_station_ctx_t *pHddStaCtx;
7247 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7248 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307249 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307250 eHalStatus status;
7251 int ret_val;
7252 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7253 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7254 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307255 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7256 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7257 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307258 };
7259
7260 ENTER();
7261
7262 if (VOS_FTM_MODE == hdd_get_conparam()) {
7263 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7264 return -EINVAL;
7265 }
7266
7267 ret_val = wlan_hdd_validate_context(pHddCtx);
7268 if (ret_val) {
7269 return ret_val;
7270 }
7271
7272 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7273
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307274 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7275 hddLog(LOGE, FL("Invalid ATTR"));
7276 return -EINVAL;
7277 }
7278
7279 /* check the Wifi Capability */
7280 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7281 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7282 {
7283 hddLog(VOS_TRACE_LEVEL_ERROR,
7284 FL("WIFICONFIG not supported by Firmware"));
7285 return -EINVAL;
7286 }
7287
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307288 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7289 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7290 modifyRoamParamsReq.value =
7291 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7292
7293 if (eHAL_STATUS_SUCCESS !=
7294 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7295 {
7296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7297 ret_val = -EINVAL;
7298 }
7299 return ret_val;
7300 }
7301
7302 /* Moved this down in order to provide provision to set beacon
7303 * miss penalty count irrespective of connection state.
7304 */
7305 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7306 hddLog(LOGE, FL("Not in Connected state!"));
7307 return -ENOTSUPP;
7308 }
7309
7310 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307311
7312 if (!pReq) {
7313 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7314 "%s: Not able to allocate memory for tSetWifiConfigParams",
7315 __func__);
7316 return eHAL_STATUS_E_MALLOC_FAILED;
7317 }
7318
7319 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7320
7321 pReq->sessionId = pAdapter->sessionId;
7322 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7323
7324 if (tb[PARAM_MODULATED_DTIM]) {
7325 pReq->paramValue = nla_get_u32(
7326 tb[PARAM_MODULATED_DTIM]);
7327 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7328 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307329 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307330 hdd_set_pwrparams(pHddCtx);
7331 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7332 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7333
7334 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7335 iw_full_power_cbfn, pAdapter,
7336 eSME_FULL_PWR_NEEDED_BY_HDD);
7337 }
7338 else
7339 {
7340 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7341 }
7342 }
7343
7344 if (tb[PARAM_STATS_AVG_FACTOR]) {
7345 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7346 pReq->paramValue = nla_get_u16(
7347 tb[PARAM_STATS_AVG_FACTOR]);
7348 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7349 pReq->paramType, pReq->paramValue);
7350 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7351
7352 if (eHAL_STATUS_SUCCESS != status)
7353 {
7354 vos_mem_free(pReq);
7355 pReq = NULL;
7356 ret_val = -EPERM;
7357 return ret_val;
7358 }
7359 }
7360
7361
7362 if (tb[PARAM_GUARD_TIME]) {
7363 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7364 pReq->paramValue = nla_get_u32(
7365 tb[PARAM_GUARD_TIME]);
7366 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7367 pReq->paramType, pReq->paramValue);
7368 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7369
7370 if (eHAL_STATUS_SUCCESS != status)
7371 {
7372 vos_mem_free(pReq);
7373 pReq = NULL;
7374 ret_val = -EPERM;
7375 return ret_val;
7376 }
7377
7378 }
7379
7380 EXIT();
7381 return ret_val;
7382}
7383
7384/**
7385 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7386 * vendor command
7387 *
7388 * @wiphy: wiphy device pointer
7389 * @wdev: wireless device pointer
7390 * @data: Vendor command data buffer
7391 * @data_len: Buffer length
7392 *
7393 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7394 *
7395 * Return: EOK or other error codes.
7396 */
7397static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7398 struct wireless_dev *wdev,
7399 const void *data,
7400 int data_len)
7401{
7402 int ret;
7403
7404 vos_ssr_protect(__func__);
7405 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7406 data, data_len);
7407 vos_ssr_unprotect(__func__);
7408
7409 return ret;
7410}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307411const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7412{
Mukul Sharma2a271632014-10-13 14:59:01 +05307413 {
7414 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7415 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7416 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7417 WIPHY_VENDOR_CMD_NEED_NETDEV |
7418 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307419 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307420 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307421
7422 {
7423 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7424 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7425 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7426 WIPHY_VENDOR_CMD_NEED_NETDEV |
7427 WIPHY_VENDOR_CMD_NEED_RUNNING,
7428 .doit = wlan_hdd_cfg80211_nan_request
7429 },
7430
Sunil Duttc69bccb2014-05-26 21:30:20 +05307431#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7432 {
7433 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7434 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7435 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7436 WIPHY_VENDOR_CMD_NEED_NETDEV |
7437 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307438 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307439 },
7440
7441 {
7442 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7443 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7444 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7445 WIPHY_VENDOR_CMD_NEED_NETDEV |
7446 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307447 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307448 },
7449
7450 {
7451 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7452 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7453 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7454 WIPHY_VENDOR_CMD_NEED_NETDEV |
7455 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307456 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307457 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307458#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307459#ifdef WLAN_FEATURE_EXTSCAN
7460 {
7461 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7462 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7463 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7464 WIPHY_VENDOR_CMD_NEED_NETDEV |
7465 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307466 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307467 },
7468 {
7469 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7470 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7471 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7472 WIPHY_VENDOR_CMD_NEED_NETDEV |
7473 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307474 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307475 },
7476 {
7477 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7478 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7479 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7480 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307481 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307482 },
7483 {
7484 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7485 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7486 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7487 WIPHY_VENDOR_CMD_NEED_NETDEV |
7488 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307489 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307490 },
7491 {
7492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7495 WIPHY_VENDOR_CMD_NEED_NETDEV |
7496 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307497 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307498 },
7499 {
7500 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7501 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7502 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7503 WIPHY_VENDOR_CMD_NEED_NETDEV |
7504 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307505 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307506 },
7507 {
7508 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7509 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7510 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7511 WIPHY_VENDOR_CMD_NEED_NETDEV |
7512 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307513 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307514 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307515 {
7516 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7517 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7518 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7519 WIPHY_VENDOR_CMD_NEED_NETDEV |
7520 WIPHY_VENDOR_CMD_NEED_RUNNING,
7521 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7522 },
7523 {
7524 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7525 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7526 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7527 WIPHY_VENDOR_CMD_NEED_NETDEV |
7528 WIPHY_VENDOR_CMD_NEED_RUNNING,
7529 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7530 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307531#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307532/*EXT TDLS*/
7533 {
7534 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7535 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7536 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7537 WIPHY_VENDOR_CMD_NEED_NETDEV |
7538 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307539 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307540 },
7541 {
7542 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7543 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7544 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7545 WIPHY_VENDOR_CMD_NEED_NETDEV |
7546 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307547 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307548 },
7549 {
7550 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7551 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7552 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7553 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307554 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307555 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307556 {
7557 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7558 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7559 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7560 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307561 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307562 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307563 {
7564 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7565 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7566 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7567 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307568 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307569 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307570 {
7571 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7572 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7573 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7574 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307575 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307576 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307577 {
7578 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7579 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7580 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7581 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307582 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307583 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307584 {
7585 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307586 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7587 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7588 WIPHY_VENDOR_CMD_NEED_NETDEV |
7589 WIPHY_VENDOR_CMD_NEED_RUNNING,
7590 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7591 },
7592 {
7593 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307594 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7595 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7596 WIPHY_VENDOR_CMD_NEED_NETDEV |
7597 WIPHY_VENDOR_CMD_NEED_RUNNING,
7598 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307599 },
7600 {
7601 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7602 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7603 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7604 WIPHY_VENDOR_CMD_NEED_NETDEV,
7605 .doit = wlan_hdd_cfg80211_wifi_logger_start
7606 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307607 {
7608 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7609 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7610 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7611 WIPHY_VENDOR_CMD_NEED_NETDEV|
7612 WIPHY_VENDOR_CMD_NEED_RUNNING,
7613 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307614 },
7615 {
7616 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7617 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7618 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7619 WIPHY_VENDOR_CMD_NEED_NETDEV |
7620 WIPHY_VENDOR_CMD_NEED_RUNNING,
7621 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307622 },
7623 {
7624 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7625 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7626 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7627 WIPHY_VENDOR_CMD_NEED_NETDEV |
7628 WIPHY_VENDOR_CMD_NEED_RUNNING,
7629 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307630 },
7631#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7632 {
7633 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7634 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7635 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7636 WIPHY_VENDOR_CMD_NEED_NETDEV |
7637 WIPHY_VENDOR_CMD_NEED_RUNNING,
7638 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307639 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307640#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307641 {
7642 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7643 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7644 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7645 WIPHY_VENDOR_CMD_NEED_NETDEV |
7646 WIPHY_VENDOR_CMD_NEED_RUNNING,
7647 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307648 },
7649 {
7650 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7651 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7652 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7653 WIPHY_VENDOR_CMD_NEED_NETDEV |
7654 WIPHY_VENDOR_CMD_NEED_RUNNING,
7655 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307656 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307657};
7658
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007659/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307660static const
7661struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007662{
7663#ifdef FEATURE_WLAN_CH_AVOID
7664 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307665 .vendor_id = QCA_NL80211_VENDOR_ID,
7666 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007667 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307668#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7669#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7670 {
7671 /* Index = 1*/
7672 .vendor_id = QCA_NL80211_VENDOR_ID,
7673 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7674 },
7675 {
7676 /* Index = 2*/
7677 .vendor_id = QCA_NL80211_VENDOR_ID,
7678 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7679 },
7680 {
7681 /* Index = 3*/
7682 .vendor_id = QCA_NL80211_VENDOR_ID,
7683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7684 },
7685 {
7686 /* Index = 4*/
7687 .vendor_id = QCA_NL80211_VENDOR_ID,
7688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7689 },
7690 {
7691 /* Index = 5*/
7692 .vendor_id = QCA_NL80211_VENDOR_ID,
7693 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7694 },
7695 {
7696 /* Index = 6*/
7697 .vendor_id = QCA_NL80211_VENDOR_ID,
7698 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7699 },
7700#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307701#ifdef WLAN_FEATURE_EXTSCAN
7702 {
7703 .vendor_id = QCA_NL80211_VENDOR_ID,
7704 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7705 },
7706 {
7707 .vendor_id = QCA_NL80211_VENDOR_ID,
7708 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7709 },
7710 {
7711 .vendor_id = QCA_NL80211_VENDOR_ID,
7712 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7713 },
7714 {
7715 .vendor_id = QCA_NL80211_VENDOR_ID,
7716 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7717 },
7718 {
7719 .vendor_id = QCA_NL80211_VENDOR_ID,
7720 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7721 },
7722 {
7723 .vendor_id = QCA_NL80211_VENDOR_ID,
7724 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7725 },
7726 {
7727 .vendor_id = QCA_NL80211_VENDOR_ID,
7728 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7729 },
7730 {
7731 .vendor_id = QCA_NL80211_VENDOR_ID,
7732 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7733 },
7734 {
7735 .vendor_id = QCA_NL80211_VENDOR_ID,
7736 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7737 },
7738 {
7739 .vendor_id = QCA_NL80211_VENDOR_ID,
7740 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7741 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307742 {
7743 .vendor_id = QCA_NL80211_VENDOR_ID,
7744 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7745 },
7746 {
7747 .vendor_id = QCA_NL80211_VENDOR_ID,
7748 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7749 },
7750 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7751 .vendor_id = QCA_NL80211_VENDOR_ID,
7752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7753 },
7754 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7755 .vendor_id = QCA_NL80211_VENDOR_ID,
7756 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7757 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307758#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307759/*EXT TDLS*/
7760 {
7761 .vendor_id = QCA_NL80211_VENDOR_ID,
7762 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7763 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307764 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7765 .vendor_id = QCA_NL80211_VENDOR_ID,
7766 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7767 },
7768
Srinivas Dasari030bad32015-02-18 23:23:54 +05307769
7770 {
7771 .vendor_id = QCA_NL80211_VENDOR_ID,
7772 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7773 },
7774
Sushant Kaushik084f6592015-09-10 13:11:56 +05307775 {
7776 .vendor_id = QCA_NL80211_VENDOR_ID,
7777 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307778 },
7779 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7780 .vendor_id = QCA_NL80211_VENDOR_ID,
7781 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7782 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307783 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7784 .vendor_id = QCA_NL80211_VENDOR_ID,
7785 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7786 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307787
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007788};
7789
Jeff Johnson295189b2012-06-20 16:38:30 -07007790/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307791 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307792 * This function is called by hdd_wlan_startup()
7793 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307794 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307796struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007797{
7798 struct wiphy *wiphy;
7799 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307800 /*
7801 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007802 */
7803 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7804
7805 if (!wiphy)
7806 {
7807 /* Print error and jump into err label and free the memory */
7808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7809 return NULL;
7810 }
7811
Sunil Duttc69bccb2014-05-26 21:30:20 +05307812
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 return wiphy;
7814}
7815
7816/*
7817 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307818 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 * private ioctl to change the band value
7820 */
7821int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7822{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307823 int i, j;
7824 eNVChannelEnabledType channelEnabledState;
7825
Jeff Johnsone7245742012-09-05 17:12:55 -07007826 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307827
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307828 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007829 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307830
7831 if (NULL == wiphy->bands[i])
7832 {
7833 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7834 __func__, i);
7835 continue;
7836 }
7837
7838 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7839 {
7840 struct ieee80211_supported_band *band = wiphy->bands[i];
7841
7842 channelEnabledState = vos_nv_getChannelEnabledState(
7843 band->channels[j].hw_value);
7844
7845 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7846 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307847 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307848 continue;
7849 }
7850 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7851 {
7852 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7853 continue;
7854 }
7855
7856 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7857 NV_CHANNEL_INVALID == channelEnabledState)
7858 {
7859 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7860 }
7861 else if (NV_CHANNEL_DFS == channelEnabledState)
7862 {
7863 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7864 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7865 }
7866 else
7867 {
7868 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7869 |IEEE80211_CHAN_RADAR);
7870 }
7871 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 }
7873 return 0;
7874}
7875/*
7876 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307877 * This function is called by hdd_wlan_startup()
7878 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 * This function is used to initialize and register wiphy structure.
7880 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307881int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 struct wiphy *wiphy,
7883 hdd_config_t *pCfg
7884 )
7885{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307886 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307887 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7888
Jeff Johnsone7245742012-09-05 17:12:55 -07007889 ENTER();
7890
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 /* Now bind the underlying wlan device with wiphy */
7892 set_wiphy_dev(wiphy, dev);
7893
7894 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007895
Kiet Lam6c583332013-10-14 05:37:09 +05307896#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007897 /* the flag for the other case would be initialzed in
7898 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007899 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307900#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007901
Amar Singhalfddc28c2013-09-05 13:03:40 -07007902 /* This will disable updating of NL channels from passive to
7903 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7905 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7906#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007907 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307908#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007909
Amar Singhala49cbc52013-10-08 18:37:44 -07007910
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007912 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7913 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7914 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007915 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7917 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7918#else
7919 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7920#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007921#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007922
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007923#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007924 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007925#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007926 || pCfg->isFastRoamIniFeatureEnabled
7927#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007928#ifdef FEATURE_WLAN_ESE
7929 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007930#endif
7931 )
7932 {
7933 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7934 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007935#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007936#ifdef FEATURE_WLAN_TDLS
7937 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7938 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7939#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307940#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307941 if (pCfg->configPNOScanSupport)
7942 {
7943 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7944 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7945 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7946 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7947 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307948#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007949
Abhishek Singh10d85972015-04-17 10:27:23 +05307950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7951 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7952#endif
7953
Amar Singhalfddc28c2013-09-05 13:03:40 -07007954#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007955 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7956 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007957 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007958 driver need to determine what to do with both
7959 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007960
7961 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007962#else
7963 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007964#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007965
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307966 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7967
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307968 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007969
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307970 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7971
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307973 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7974 | BIT(NL80211_IFTYPE_ADHOC)
7975 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7976 | BIT(NL80211_IFTYPE_P2P_GO)
7977 | BIT(NL80211_IFTYPE_AP);
7978
7979 if (VOS_MONITOR_MODE == hdd_get_conparam())
7980 {
7981 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007983
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307984 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007985 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7987 if( pCfg->enableMCC )
7988 {
7989 /* Currently, supports up to two channels */
7990 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007991
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307992 if( !pCfg->allowMCCGODiffBI )
7993 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007994
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307995 }
7996 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7997 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007998#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307999 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008000
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 /* Before registering we need to update the ht capabilitied based
8002 * on ini values*/
8003 if( !pCfg->ShortGI20MhzEnable )
8004 {
8005 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8006 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008007 }
8008
8009 if( !pCfg->ShortGI40MhzEnable )
8010 {
8011 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8012 }
8013
8014 if( !pCfg->nChannelBondingMode5GHz )
8015 {
8016 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8017 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308018 /*
8019 * In case of static linked driver at the time of driver unload,
8020 * module exit doesn't happens. Module cleanup helps in cleaning
8021 * of static memory.
8022 * If driver load happens statically, at the time of driver unload,
8023 * wiphy flags don't get reset because of static memory.
8024 * It's better not to store channel in static memory.
8025 */
8026 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8027 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8028 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8029 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8030 {
8031 hddLog(VOS_TRACE_LEVEL_ERROR,
8032 FL("Not enough memory to allocate channels"));
8033 return -ENOMEM;
8034 }
8035 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8036 &hdd_channels_2_4_GHZ[0],
8037 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008038
Agrawal Ashish97dec502015-11-26 20:20:58 +05308039 if (true == hdd_is_5g_supported(pHddCtx))
8040 {
8041 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8042 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8043 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8044 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8045 {
8046 hddLog(VOS_TRACE_LEVEL_ERROR,
8047 FL("Not enough memory to allocate channels"));
8048 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8049 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8050 return -ENOMEM;
8051 }
8052 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8053 &hdd_channels_5_GHZ[0],
8054 sizeof(hdd_channels_5_GHZ));
8055 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308056
8057 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8058 {
8059
8060 if (NULL == wiphy->bands[i])
8061 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308062 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308063 __func__, i);
8064 continue;
8065 }
8066
8067 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8068 {
8069 struct ieee80211_supported_band *band = wiphy->bands[i];
8070
8071 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8072 {
8073 // Enable social channels for P2P
8074 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8075 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8076 else
8077 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8078 continue;
8079 }
8080 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8081 {
8082 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8083 continue;
8084 }
8085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 }
8087 /*Initialise the supported cipher suite details*/
8088 wiphy->cipher_suites = hdd_cipher_suites;
8089 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8090
8091 /*signal strength in mBm (100*dBm) */
8092 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8093
8094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308095 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008096#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008097
Sunil Duttc69bccb2014-05-26 21:30:20 +05308098 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8099 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008100 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8101 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8102
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308103 EXIT();
8104 return 0;
8105}
8106
8107/* In this function we are registering wiphy. */
8108int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8109{
8110 ENTER();
8111 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008112 if (0 > wiphy_register(wiphy))
8113 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308114 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8116 return -EIO;
8117 }
8118
8119 EXIT();
8120 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308121}
Jeff Johnson295189b2012-06-20 16:38:30 -07008122
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308123/* In this function we are updating channel list when,
8124 regulatory domain is FCC and country code is US.
8125 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8126 As per FCC smart phone is not a indoor device.
8127 GO should not opeate on indoor channels */
8128void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8129{
8130 int j;
8131 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8132 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8133 //Default counrtycode from NV at the time of wiphy initialization.
8134 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8135 &defaultCountryCode[0]))
8136 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008137 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308138 }
8139 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8140 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308141 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8142 {
8143 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8144 return;
8145 }
8146 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8147 {
8148 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8149 // Mark UNII -1 band channel as passive
8150 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8151 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8152 }
8153 }
8154}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308155/* This function registers for all frame which supplicant is interested in */
8156void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008157{
Jeff Johnson295189b2012-06-20 16:38:30 -07008158 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8159 /* Register for all P2P action, public action etc frames */
8160 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008161 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308162 /* Register frame indication call back */
8163 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 /* Right now we are registering these frame when driver is getting
8165 initialized. Once we will move to 2.6.37 kernel, in which we have
8166 frame register ops, we will move this code as a part of that */
8167 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308168 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8170
8171 /* GAS Initial Response */
8172 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8173 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308174
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 /* GAS Comeback Request */
8176 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8177 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8178
8179 /* GAS Comeback Response */
8180 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8181 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8182
8183 /* P2P Public Action */
8184 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308185 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008186 P2P_PUBLIC_ACTION_FRAME_SIZE );
8187
8188 /* P2P Action */
8189 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8190 (v_U8_t*)P2P_ACTION_FRAME,
8191 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008192
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308193 /* WNM BSS Transition Request frame */
8194 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8195 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8196 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008197
8198 /* WNM-Notification */
8199 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8200 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8201 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008202}
8203
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308204void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008205{
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8207 /* Register for all P2P action, public action etc frames */
8208 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8209
Jeff Johnsone7245742012-09-05 17:12:55 -07008210 ENTER();
8211
Jeff Johnson295189b2012-06-20 16:38:30 -07008212 /* Right now we are registering these frame when driver is getting
8213 initialized. Once we will move to 2.6.37 kernel, in which we have
8214 frame register ops, we will move this code as a part of that */
8215 /* GAS Initial Request */
8216
8217 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8218 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8219
8220 /* GAS Initial Response */
8221 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8222 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308223
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 /* GAS Comeback Request */
8225 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8226 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8227
8228 /* GAS Comeback Response */
8229 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8230 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8231
8232 /* P2P Public Action */
8233 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308234 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 P2P_PUBLIC_ACTION_FRAME_SIZE );
8236
8237 /* P2P Action */
8238 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8239 (v_U8_t*)P2P_ACTION_FRAME,
8240 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008241 /* WNM-Notification */
8242 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8243 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8244 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008245}
8246
8247#ifdef FEATURE_WLAN_WAPI
8248void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308249 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008250{
8251 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8252 tCsrRoamSetKey setKey;
8253 v_BOOL_t isConnected = TRUE;
8254 int status = 0;
8255 v_U32_t roamId= 0xFF;
8256 tANI_U8 *pKeyPtr = NULL;
8257 int n = 0;
8258
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308259 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8260 __func__, hdd_device_modetoString(pAdapter->device_mode),
8261 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008262
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308263 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 setKey.keyId = key_index; // Store Key ID
8265 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8266 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8267 setKey.paeRole = 0 ; // the PAE role
8268 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8269 {
8270 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8271 }
8272 else
8273 {
8274 isConnected = hdd_connIsConnected(pHddStaCtx);
8275 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8276 }
8277 setKey.keyLength = key_Len;
8278 pKeyPtr = setKey.Key;
8279 memcpy( pKeyPtr, key, key_Len);
8280
Arif Hussain6d2a3322013-11-17 19:50:10 -08008281 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 __func__, key_Len);
8283 for (n = 0 ; n < key_Len; n++)
8284 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8285 __func__,n,setKey.Key[n]);
8286
8287 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8288 if ( isConnected )
8289 {
8290 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8291 pAdapter->sessionId, &setKey, &roamId );
8292 }
8293 if ( status != 0 )
8294 {
8295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8296 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8297 __LINE__, status );
8298 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8299 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308300 /* Need to clear any trace of key value in the memory.
8301 * Thus zero out the memory even though it is local
8302 * variable.
8303 */
8304 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008305}
8306#endif /* FEATURE_WLAN_WAPI*/
8307
8308#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308309int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 beacon_data_t **ppBeacon,
8311 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008312#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308313int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008314 beacon_data_t **ppBeacon,
8315 struct cfg80211_beacon_data *params,
8316 int dtim_period)
8317#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308318{
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 int size;
8320 beacon_data_t *beacon = NULL;
8321 beacon_data_t *old = NULL;
8322 int head_len,tail_len;
8323
Jeff Johnsone7245742012-09-05 17:12:55 -07008324 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008325 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308326 {
8327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8328 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008329 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308330 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008331
8332 old = pAdapter->sessionCtx.ap.beacon;
8333
8334 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308335 {
8336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8337 FL("session(%d) old and new heads points to NULL"),
8338 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308340 }
8341
8342 if (params->tail && !params->tail_len)
8343 {
8344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8345 FL("tail_len is zero but tail is not NULL"));
8346 return -EINVAL;
8347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008348
Jeff Johnson295189b2012-06-20 16:38:30 -07008349#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8350 /* Kernel 3.0 is not updating dtim_period for set beacon */
8351 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308352 {
8353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8354 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008357#endif
8358
8359 if(params->head)
8360 head_len = params->head_len;
8361 else
8362 head_len = old->head_len;
8363
8364 if(params->tail || !old)
8365 tail_len = params->tail_len;
8366 else
8367 tail_len = old->tail_len;
8368
8369 size = sizeof(beacon_data_t) + head_len + tail_len;
8370
8371 beacon = kzalloc(size, GFP_KERNEL);
8372
8373 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308374 {
8375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8376 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008377 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308378 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008379
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008380#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008381 if(params->dtim_period || !old )
8382 beacon->dtim_period = params->dtim_period;
8383 else
8384 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008385#else
8386 if(dtim_period || !old )
8387 beacon->dtim_period = dtim_period;
8388 else
8389 beacon->dtim_period = old->dtim_period;
8390#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308391
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8393 beacon->tail = beacon->head + head_len;
8394 beacon->head_len = head_len;
8395 beacon->tail_len = tail_len;
8396
8397 if(params->head) {
8398 memcpy (beacon->head,params->head,beacon->head_len);
8399 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308400 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 if(old)
8402 memcpy (beacon->head,old->head,beacon->head_len);
8403 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308404
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 if(params->tail) {
8406 memcpy (beacon->tail,params->tail,beacon->tail_len);
8407 }
8408 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308409 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 memcpy (beacon->tail,old->tail,beacon->tail_len);
8411 }
8412
8413 *ppBeacon = beacon;
8414
8415 kfree(old);
8416
8417 return 0;
8418
8419}
Jeff Johnson295189b2012-06-20 16:38:30 -07008420
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308421v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8423 const v_U8_t *pIes,
8424#else
8425 v_U8_t *pIes,
8426#endif
8427 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008428{
8429 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308430 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308432
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308434 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 elem_id = ptr[0];
8436 elem_len = ptr[1];
8437 left -= 2;
8438 if(elem_len > left)
8439 {
8440 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008441 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008442 eid,elem_len,left);
8443 return NULL;
8444 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308445 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008446 {
8447 return ptr;
8448 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308449
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 left -= elem_len;
8451 ptr += (elem_len + 2);
8452 }
8453 return NULL;
8454}
8455
Jeff Johnson295189b2012-06-20 16:38:30 -07008456/* Check if rate is 11g rate or not */
8457static int wlan_hdd_rate_is_11g(u8 rate)
8458{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008459 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 u8 i;
8461 for (i = 0; i < 8; i++)
8462 {
8463 if(rate == gRateArray[i])
8464 return TRUE;
8465 }
8466 return FALSE;
8467}
8468
8469/* Check for 11g rate and set proper 11g only mode */
8470static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8471 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8472{
8473 u8 i, num_rates = pIe[0];
8474
8475 pIe += 1;
8476 for ( i = 0; i < num_rates; i++)
8477 {
8478 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8479 {
8480 /* If rate set have 11g rate than change the mode to 11G */
8481 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8482 if (pIe[i] & BASIC_RATE_MASK)
8483 {
8484 /* If we have 11g rate as basic rate, it means mode
8485 is 11g only mode.
8486 */
8487 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8488 *pCheckRatesfor11g = FALSE;
8489 }
8490 }
8491 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8492 {
8493 *require_ht = TRUE;
8494 }
8495 }
8496 return;
8497}
8498
8499static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8500{
8501 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8502 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8503 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8504 u8 checkRatesfor11g = TRUE;
8505 u8 require_ht = FALSE;
8506 u8 *pIe=NULL;
8507
8508 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8509
8510 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8511 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8512 if (pIe != NULL)
8513 {
8514 pIe += 1;
8515 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8516 &pConfig->SapHw_mode);
8517 }
8518
8519 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8520 WLAN_EID_EXT_SUPP_RATES);
8521 if (pIe != NULL)
8522 {
8523
8524 pIe += 1;
8525 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8526 &pConfig->SapHw_mode);
8527 }
8528
8529 if( pConfig->channel > 14 )
8530 {
8531 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8532 }
8533
8534 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8535 WLAN_EID_HT_CAPABILITY);
8536
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308537 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 {
8539 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8540 if(require_ht)
8541 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8542 }
8543}
8544
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308545static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8546 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8547{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008548 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308549 v_U8_t *pIe = NULL;
8550 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8551
8552 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8553 pBeacon->tail, pBeacon->tail_len);
8554
8555 if (pIe)
8556 {
8557 ielen = pIe[1] + 2;
8558 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8559 {
8560 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8561 }
8562 else
8563 {
8564 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8565 return -EINVAL;
8566 }
8567 *total_ielen += ielen;
8568 }
8569 return 0;
8570}
8571
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008572static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8573 v_U8_t *genie, v_U8_t *total_ielen)
8574{
8575 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8576 int left = pBeacon->tail_len;
8577 v_U8_t *ptr = pBeacon->tail;
8578 v_U8_t elem_id, elem_len;
8579 v_U16_t ielen = 0;
8580
8581 if ( NULL == ptr || 0 == left )
8582 return;
8583
8584 while (left >= 2)
8585 {
8586 elem_id = ptr[0];
8587 elem_len = ptr[1];
8588 left -= 2;
8589 if (elem_len > left)
8590 {
8591 hddLog( VOS_TRACE_LEVEL_ERROR,
8592 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8593 elem_id, elem_len, left);
8594 return;
8595 }
8596 if (IE_EID_VENDOR == elem_id)
8597 {
8598 /* skipping the VSIE's which we don't want to include or
8599 * it will be included by existing code
8600 */
8601 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8602#ifdef WLAN_FEATURE_WFD
8603 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8604#endif
8605 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8606 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8607 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8608 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8609 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8610 {
8611 ielen = ptr[1] + 2;
8612 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8613 {
8614 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8615 *total_ielen += ielen;
8616 }
8617 else
8618 {
8619 hddLog( VOS_TRACE_LEVEL_ERROR,
8620 "IE Length is too big "
8621 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8622 elem_id, elem_len, *total_ielen);
8623 }
8624 }
8625 }
8626
8627 left -= elem_len;
8628 ptr += (elem_len + 2);
8629 }
8630 return;
8631}
8632
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008633#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008634static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8635 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008636#else
8637static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8638 struct cfg80211_beacon_data *params)
8639#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008640{
8641 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308642 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008643 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008644 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008645
8646 genie = vos_mem_malloc(MAX_GENIE_LEN);
8647
8648 if(genie == NULL) {
8649
8650 return -ENOMEM;
8651 }
8652
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308653 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8654 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008655 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308656 hddLog(LOGE,
8657 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308658 ret = -EINVAL;
8659 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008660 }
8661
8662#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308663 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8664 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8665 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308666 hddLog(LOGE,
8667 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308668 ret = -EINVAL;
8669 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 }
8671#endif
8672
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308673 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8674 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308676 hddLog(LOGE,
8677 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308678 ret = -EINVAL;
8679 goto done;
8680 }
8681
8682 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8683 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008684 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008686
8687 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8688 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8689 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8690 {
8691 hddLog(LOGE,
8692 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008693 ret = -EINVAL;
8694 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008695 }
8696
8697 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8698 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8699 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8700 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8701 ==eHAL_STATUS_FAILURE)
8702 {
8703 hddLog(LOGE,
8704 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008705 ret = -EINVAL;
8706 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 }
8708
8709 // Added for ProResp IE
8710 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8711 {
8712 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8713 u8 probe_rsp_ie_len[3] = {0};
8714 u8 counter = 0;
8715 /* Check Probe Resp Length if it is greater then 255 then Store
8716 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8717 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8718 Store More then 255 bytes into One Variable.
8719 */
8720 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8721 {
8722 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8723 {
8724 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8725 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8726 }
8727 else
8728 {
8729 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8730 rem_probe_resp_ie_len = 0;
8731 }
8732 }
8733
8734 rem_probe_resp_ie_len = 0;
8735
8736 if (probe_rsp_ie_len[0] > 0)
8737 {
8738 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8739 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8740 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8741 probe_rsp_ie_len[0], NULL,
8742 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8743 {
8744 hddLog(LOGE,
8745 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008746 ret = -EINVAL;
8747 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008748 }
8749 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8750 }
8751
8752 if (probe_rsp_ie_len[1] > 0)
8753 {
8754 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8755 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8756 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8757 probe_rsp_ie_len[1], NULL,
8758 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8759 {
8760 hddLog(LOGE,
8761 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008762 ret = -EINVAL;
8763 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 }
8765 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8766 }
8767
8768 if (probe_rsp_ie_len[2] > 0)
8769 {
8770 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8771 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8772 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8773 probe_rsp_ie_len[2], NULL,
8774 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8775 {
8776 hddLog(LOGE,
8777 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008778 ret = -EINVAL;
8779 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 }
8781 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8782 }
8783
8784 if (probe_rsp_ie_len[1] == 0 )
8785 {
8786 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8787 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8788 eANI_BOOLEAN_FALSE) )
8789 {
8790 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008791 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 }
8793 }
8794
8795 if (probe_rsp_ie_len[2] == 0 )
8796 {
8797 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8798 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8799 eANI_BOOLEAN_FALSE) )
8800 {
8801 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008802 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008803 }
8804 }
8805
8806 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8807 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8808 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8809 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8810 == eHAL_STATUS_FAILURE)
8811 {
8812 hddLog(LOGE,
8813 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008814 ret = -EINVAL;
8815 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 }
8817 }
8818 else
8819 {
8820 // Reset WNI_CFG_PROBE_RSP Flags
8821 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8822
8823 hddLog(VOS_TRACE_LEVEL_INFO,
8824 "%s: No Probe Response IE received in set beacon",
8825 __func__);
8826 }
8827
8828 // Added for AssocResp IE
8829 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8830 {
8831 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8832 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8833 params->assocresp_ies_len, NULL,
8834 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8835 {
8836 hddLog(LOGE,
8837 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008838 ret = -EINVAL;
8839 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 }
8841
8842 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8843 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8844 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8845 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8846 == eHAL_STATUS_FAILURE)
8847 {
8848 hddLog(LOGE,
8849 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008850 ret = -EINVAL;
8851 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008852 }
8853 }
8854 else
8855 {
8856 hddLog(VOS_TRACE_LEVEL_INFO,
8857 "%s: No Assoc Response IE received in set beacon",
8858 __func__);
8859
8860 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8861 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8862 eANI_BOOLEAN_FALSE) )
8863 {
8864 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008865 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008866 }
8867 }
8868
Jeff Johnsone7245742012-09-05 17:12:55 -07008869done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008870 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308871 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008872}
Jeff Johnson295189b2012-06-20 16:38:30 -07008873
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308874/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 * FUNCTION: wlan_hdd_validate_operation_channel
8876 * called by wlan_hdd_cfg80211_start_bss() and
8877 * wlan_hdd_cfg80211_set_channel()
8878 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308879 * channel list.
8880 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008881VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008882{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308883
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 v_U32_t num_ch = 0;
8885 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8886 u32 indx = 0;
8887 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308888 v_U8_t fValidChannel = FALSE, count = 0;
8889 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308890
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8892
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308893 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308895 /* Validate the channel */
8896 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008897 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308898 if ( channel == rfChannels[count].channelNum )
8899 {
8900 fValidChannel = TRUE;
8901 break;
8902 }
8903 }
8904 if (fValidChannel != TRUE)
8905 {
8906 hddLog(VOS_TRACE_LEVEL_ERROR,
8907 "%s: Invalid Channel [%d]", __func__, channel);
8908 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 }
8910 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308911 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008912 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308913 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8914 valid_ch, &num_ch))
8915 {
8916 hddLog(VOS_TRACE_LEVEL_ERROR,
8917 "%s: failed to get valid channel list", __func__);
8918 return VOS_STATUS_E_FAILURE;
8919 }
8920 for (indx = 0; indx < num_ch; indx++)
8921 {
8922 if (channel == valid_ch[indx])
8923 {
8924 break;
8925 }
8926 }
8927
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308928 if (indx >= num_ch)
8929 {
8930 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8931 {
8932 eCsrBand band;
8933 unsigned int freq;
8934
8935 sme_GetFreqBand(hHal, &band);
8936
8937 if (eCSR_BAND_5G == band)
8938 {
8939#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8940 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8941 {
8942 freq = ieee80211_channel_to_frequency(channel,
8943 IEEE80211_BAND_2GHZ);
8944 }
8945 else
8946 {
8947 freq = ieee80211_channel_to_frequency(channel,
8948 IEEE80211_BAND_5GHZ);
8949 }
8950#else
8951 freq = ieee80211_channel_to_frequency(channel);
8952#endif
8953 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8954 return VOS_STATUS_SUCCESS;
8955 }
8956 }
8957
8958 hddLog(VOS_TRACE_LEVEL_ERROR,
8959 "%s: Invalid Channel [%d]", __func__, channel);
8960 return VOS_STATUS_E_FAILURE;
8961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308963
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308965
Jeff Johnson295189b2012-06-20 16:38:30 -07008966}
8967
Viral Modi3a32cc52013-02-08 11:14:52 -08008968/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308969 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008970 * This function is used to set the channel number
8971 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308972static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008973 struct ieee80211_channel *chan,
8974 enum nl80211_channel_type channel_type
8975 )
8976{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308977 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008978 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008979 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008980 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308981 hdd_context_t *pHddCtx;
8982 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008983
8984 ENTER();
8985
8986 if( NULL == dev )
8987 {
8988 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008989 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008990 return -ENODEV;
8991 }
8992 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308993
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308994 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8995 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8996 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008997 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308998 "%s: device_mode = %s (%d) freq = %d", __func__,
8999 hdd_device_modetoString(pAdapter->device_mode),
9000 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309001
9002 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9003 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309004 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009005 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309006 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009007 }
9008
9009 /*
9010 * Do freq to chan conversion
9011 * TODO: for 11a
9012 */
9013
9014 channel = ieee80211_frequency_to_channel(freq);
9015
9016 /* Check freq range */
9017 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9018 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9019 {
9020 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009021 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009022 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9023 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9024 return -EINVAL;
9025 }
9026
9027 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9028
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309029 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9030 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009031 {
9032 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
9033 {
9034 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009035 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08009036 return -EINVAL;
9037 }
9038 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9039 "%s: set channel to [%d] for device mode =%d",
9040 __func__, channel,pAdapter->device_mode);
9041 }
9042 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009043 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009044 )
9045 {
9046 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9047 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9048 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9049
9050 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9051 {
9052 /* Link is up then return cant set channel*/
9053 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009054 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009055 return -EINVAL;
9056 }
9057
9058 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9059 pHddStaCtx->conn_info.operationChannel = channel;
9060 pRoamProfile->ChannelInfo.ChannelList =
9061 &pHddStaCtx->conn_info.operationChannel;
9062 }
9063 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009064 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009065 )
9066 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309067 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9068 {
9069 if(VOS_STATUS_SUCCESS !=
9070 wlan_hdd_validate_operation_channel(pAdapter,channel))
9071 {
9072 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009073 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309074 return -EINVAL;
9075 }
9076 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9077 }
9078 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009079 {
9080 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9081
9082 /* If auto channel selection is configured as enable/ 1 then ignore
9083 channel set by supplicant
9084 */
9085 if ( cfg_param->apAutoChannelSelection )
9086 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309087 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9088 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009089 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309090 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9091 __func__, hdd_device_modetoString(pAdapter->device_mode),
9092 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009093 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309094 else
9095 {
9096 if(VOS_STATUS_SUCCESS !=
9097 wlan_hdd_validate_operation_channel(pAdapter,channel))
9098 {
9099 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009100 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309101 return -EINVAL;
9102 }
9103 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9104 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009105 }
9106 }
9107 else
9108 {
9109 hddLog(VOS_TRACE_LEVEL_FATAL,
9110 "%s: Invalid device mode failed to set valid channel", __func__);
9111 return -EINVAL;
9112 }
9113 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309114 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009115}
9116
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309117static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9118 struct net_device *dev,
9119 struct ieee80211_channel *chan,
9120 enum nl80211_channel_type channel_type
9121 )
9122{
9123 int ret;
9124
9125 vos_ssr_protect(__func__);
9126 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9127 vos_ssr_unprotect(__func__);
9128
9129 return ret;
9130}
9131
Jeff Johnson295189b2012-06-20 16:38:30 -07009132#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9133static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9134 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009135#else
9136static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9137 struct cfg80211_beacon_data *params,
9138 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309139 enum nl80211_hidden_ssid hidden_ssid,
9140 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009141#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009142{
9143 tsap_Config_t *pConfig;
9144 beacon_data_t *pBeacon = NULL;
9145 struct ieee80211_mgmt *pMgmt_frame;
9146 v_U8_t *pIe=NULL;
9147 v_U16_t capab_info;
9148 eCsrAuthType RSNAuthType;
9149 eCsrEncryptionType RSNEncryptType;
9150 eCsrEncryptionType mcRSNEncryptType;
9151 int status = VOS_STATUS_SUCCESS;
9152 tpWLAN_SAPEventCB pSapEventCallback;
9153 hdd_hostapd_state_t *pHostapdState;
9154 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9155 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309156 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009157 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309158 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009160 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309161 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009162 v_BOOL_t MFPCapable = VOS_FALSE;
9163 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309164 v_BOOL_t sapEnable11AC =
9165 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 ENTER();
9167
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309168 iniConfig = pHddCtx->cfg_ini;
9169
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9171
9172 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9173
9174 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9175
9176 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9177
9178 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9179
9180 //channel is already set in the set_channel Call back
9181 //pConfig->channel = pCommitConfig->channel;
9182
9183 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309184 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9186
9187 pConfig->dtim_period = pBeacon->dtim_period;
9188
Arif Hussain6d2a3322013-11-17 19:50:10 -08009189 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 pConfig->dtim_period);
9191
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009192 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009193 {
9194 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009195 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309196 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9197 {
9198 tANI_BOOLEAN restartNeeded;
9199 pConfig->ieee80211d = 1;
9200 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9201 sme_setRegInfo(hHal, pConfig->countryCode);
9202 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9203 }
9204 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009206 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009207 pConfig->ieee80211d = 1;
9208 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9209 sme_setRegInfo(hHal, pConfig->countryCode);
9210 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009211 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009212 else
9213 {
9214 pConfig->ieee80211d = 0;
9215 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309216 /*
9217 * If auto channel is configured i.e. channel is 0,
9218 * so skip channel validation.
9219 */
9220 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9221 {
9222 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9223 {
9224 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009225 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309226 return -EINVAL;
9227 }
9228 }
9229 else
9230 {
9231 if(1 != pHddCtx->is_dynamic_channel_range_set)
9232 {
9233 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9234 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9235 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9236 }
9237 pHddCtx->is_dynamic_channel_range_set = 0;
9238 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009240 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009241 {
9242 pConfig->ieee80211d = 0;
9243 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309244
9245#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9246 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9247 pConfig->authType = eSAP_OPEN_SYSTEM;
9248 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9249 pConfig->authType = eSAP_SHARED_KEY;
9250 else
9251 pConfig->authType = eSAP_AUTO_SWITCH;
9252#else
9253 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9254 pConfig->authType = eSAP_OPEN_SYSTEM;
9255 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9256 pConfig->authType = eSAP_SHARED_KEY;
9257 else
9258 pConfig->authType = eSAP_AUTO_SWITCH;
9259#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009260
9261 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309262
9263 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9265
9266 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9267
9268 /*Set wps station to configured*/
9269 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9270
9271 if(pIe)
9272 {
9273 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9274 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009275 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 return -EINVAL;
9277 }
9278 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9279 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009280 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 /* Check 15 bit of WPS IE as it contain information for wps state
9282 * WPS state
9283 */
9284 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9285 {
9286 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9287 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9288 {
9289 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9290 }
9291 }
9292 }
9293 else
9294 {
9295 pConfig->wps_state = SAP_WPS_DISABLED;
9296 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309297 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009298
c_hpothufe599e92014-06-16 11:38:55 +05309299 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9300 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9301 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9302 eCSR_ENCRYPT_TYPE_NONE;
9303
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 pConfig->RSNWPAReqIELength = 0;
9305 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309306 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 WLAN_EID_RSN);
9308 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309309 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9311 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9312 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309313 /* The actual processing may eventually be more extensive than
9314 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 * by the app.
9316 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309317 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9319 &RSNEncryptType,
9320 &mcRSNEncryptType,
9321 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009322 &MFPCapable,
9323 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 pConfig->pRSNWPAReqIE[1]+2,
9325 pConfig->pRSNWPAReqIE );
9326
9327 if( VOS_STATUS_SUCCESS == status )
9328 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309329 /* Now copy over all the security attributes you have
9330 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 * */
9332 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9333 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9334 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9335 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309336 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009337 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9339 }
9340 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9343 pBeacon->tail, pBeacon->tail_len);
9344
9345 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9346 {
9347 if (pConfig->pRSNWPAReqIE)
9348 {
9349 /*Mixed mode WPA/WPA2*/
9350 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9351 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9352 }
9353 else
9354 {
9355 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9356 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9357 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309358 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9360 &RSNEncryptType,
9361 &mcRSNEncryptType,
9362 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009363 &MFPCapable,
9364 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 pConfig->pRSNWPAReqIE[1]+2,
9366 pConfig->pRSNWPAReqIE );
9367
9368 if( VOS_STATUS_SUCCESS == status )
9369 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309370 /* Now copy over all the security attributes you have
9371 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 * */
9373 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9374 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9375 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9376 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309377 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009378 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9380 }
9381 }
9382 }
9383
Jeff Johnson4416a782013-03-25 14:17:50 -07009384 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9385 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9386 return -EINVAL;
9387 }
9388
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9390
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009391#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 if (params->ssid != NULL)
9393 {
9394 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9395 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9396 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9397 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9398 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009399#else
9400 if (ssid != NULL)
9401 {
9402 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9403 pConfig->SSIDinfo.ssid.length = ssid_len;
9404 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9405 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9406 }
9407#endif
9408
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309409 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309411
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 /* default value */
9413 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9414 pConfig->num_accept_mac = 0;
9415 pConfig->num_deny_mac = 0;
9416
9417 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9418 pBeacon->tail, pBeacon->tail_len);
9419
9420 /* pIe for black list is following form:
9421 type : 1 byte
9422 length : 1 byte
9423 OUI : 4 bytes
9424 acl type : 1 byte
9425 no of mac addr in black list: 1 byte
9426 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309427 */
9428 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 {
9430 pConfig->SapMacaddr_acl = pIe[6];
9431 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009432 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309434 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9435 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9437 for (i = 0; i < pConfig->num_deny_mac; i++)
9438 {
9439 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9440 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309441 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 }
9443 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9444 pBeacon->tail, pBeacon->tail_len);
9445
9446 /* pIe for white list is following form:
9447 type : 1 byte
9448 length : 1 byte
9449 OUI : 4 bytes
9450 acl type : 1 byte
9451 no of mac addr in white list: 1 byte
9452 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453 */
9454 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 {
9456 pConfig->SapMacaddr_acl = pIe[6];
9457 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009458 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309460 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9461 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9463 for (i = 0; i < pConfig->num_accept_mac; i++)
9464 {
9465 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9466 acl_entry++;
9467 }
9468 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309469
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9471
Jeff Johnsone7245742012-09-05 17:12:55 -07009472#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009473 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309474 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9475 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309476 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9477 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009478 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9479 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309480 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9481 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009482 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309483 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009484 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309485 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009486
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309487 /* If ACS disable and selected channel <= 14
9488 * OR
9489 * ACS enabled and ACS operating band is choosen as 2.4
9490 * AND
9491 * VHT in 2.4G Disabled
9492 * THEN
9493 * Fallback to 11N mode
9494 */
9495 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9496 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309497 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309498 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009499 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309500 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9501 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009502 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9503 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009504 }
9505#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309506
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 // ht_capab is not what the name conveys,this is used for protection bitmap
9508 pConfig->ht_capab =
9509 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9510
9511 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9512 {
9513 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9514 return -EINVAL;
9515 }
9516
9517 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309518 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9520 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309521 pConfig->obssProtEnabled =
9522 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009523
Chet Lanctot8cecea22014-02-11 19:09:36 -08009524#ifdef WLAN_FEATURE_11W
9525 pConfig->mfpCapable = MFPCapable;
9526 pConfig->mfpRequired = MFPRequired;
9527 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9528 pConfig->mfpCapable, pConfig->mfpRequired);
9529#endif
9530
Arif Hussain6d2a3322013-11-17 19:50:10 -08009531 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009533 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9534 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9535 (int)pConfig->channel);
9536 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9537 pConfig->SapHw_mode, pConfig->privacy,
9538 pConfig->authType);
9539 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9540 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9541 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9542 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009543
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309544 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 {
9546 //Bss already started. just return.
9547 //TODO Probably it should update some beacon params.
9548 hddLog( LOGE, "Bss Already started...Ignore the request");
9549 EXIT();
9550 return 0;
9551 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309552
Agarwal Ashish51325b52014-06-16 16:50:49 +05309553 if (vos_max_concurrent_connections_reached()) {
9554 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9555 return -EINVAL;
9556 }
9557
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 pConfig->persona = pHostapdAdapter->device_mode;
9559
Peng Xu2446a892014-09-05 17:21:18 +05309560 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9561 if ( NULL != psmeConfig)
9562 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309563 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309564 sme_GetConfigParam(hHal, psmeConfig);
9565 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309566#ifdef WLAN_FEATURE_AP_HT40_24G
9567 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9568 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9569 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9570 {
9571 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9572 sme_UpdateConfig (hHal, psmeConfig);
9573 }
9574#endif
Peng Xu2446a892014-09-05 17:21:18 +05309575 vos_mem_free(psmeConfig);
9576 }
Peng Xuafc34e32014-09-25 13:23:55 +05309577 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309578
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 pSapEventCallback = hdd_hostapd_SAPEventCB;
9580 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9581 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9582 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009583 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 return -EINVAL;
9585 }
9586
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9589
9590 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309591
Jeff Johnson295189b2012-06-20 16:38:30 -07009592 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309593 {
9594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009595 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009596 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 VOS_ASSERT(0);
9598 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309599
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309601 /* Initialize WMM configuation */
9602 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309603 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009604
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009605#ifdef WLAN_FEATURE_P2P_DEBUG
9606 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9607 {
9608 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9609 {
9610 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9611 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009612 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009613 }
9614 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9615 {
9616 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9617 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009618 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009619 }
9620 }
9621#endif
9622
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 pHostapdState->bCommit = TRUE;
9624 EXIT();
9625
9626 return 0;
9627}
9628
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009629#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309630static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309631 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 struct beacon_parameters *params)
9633{
9634 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309635 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309636 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009637
9638 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309639
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309640 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9641 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9642 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309643 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9644 hdd_device_modetoString(pAdapter->device_mode),
9645 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009646
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309647 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9648 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309649 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009650 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309651 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009652 }
9653
Agarwal Ashish51325b52014-06-16 16:50:49 +05309654 if (vos_max_concurrent_connections_reached()) {
9655 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9656 return -EINVAL;
9657 }
9658
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309659 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 )
9662 {
9663 beacon_data_t *old,*new;
9664
9665 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309666
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309668 {
9669 hddLog(VOS_TRACE_LEVEL_WARN,
9670 FL("already beacon info added to session(%d)"),
9671 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309673 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009674
9675 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9676
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309677 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009678 {
9679 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009680 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 return -EINVAL;
9682 }
9683
9684 pAdapter->sessionCtx.ap.beacon = new;
9685
9686 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9687 }
9688
9689 EXIT();
9690 return status;
9691}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309692
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309693static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9694 struct net_device *dev,
9695 struct beacon_parameters *params)
9696{
9697 int ret;
9698
9699 vos_ssr_protect(__func__);
9700 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9701 vos_ssr_unprotect(__func__);
9702
9703 return ret;
9704}
9705
9706static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 struct net_device *dev,
9708 struct beacon_parameters *params)
9709{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309710 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309711 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9712 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309713 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009714
9715 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309716
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309717 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9718 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9719 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9720 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9721 __func__, hdd_device_modetoString(pAdapter->device_mode),
9722 pAdapter->device_mode);
9723
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309724 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9725 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309726 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009727 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309728 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009729 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309730
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309731 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309733 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 {
9735 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309736
Jeff Johnson295189b2012-06-20 16:38:30 -07009737 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309738
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309740 {
9741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9742 FL("session(%d) old and new heads points to NULL"),
9743 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309745 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009746
9747 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9748
9749 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309750 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009751 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 return -EINVAL;
9753 }
9754
9755 pAdapter->sessionCtx.ap.beacon = new;
9756
9757 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9758 }
9759
9760 EXIT();
9761 return status;
9762}
9763
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309764static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9765 struct net_device *dev,
9766 struct beacon_parameters *params)
9767{
9768 int ret;
9769
9770 vos_ssr_protect(__func__);
9771 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9772 vos_ssr_unprotect(__func__);
9773
9774 return ret;
9775}
9776
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009777#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9778
9779#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309780static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009782#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309783static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009784 struct net_device *dev)
9785#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009786{
9787 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009788 hdd_context_t *pHddCtx = NULL;
9789 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309790 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309791 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009792
9793 ENTER();
9794
9795 if (NULL == pAdapter)
9796 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009798 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 return -ENODEV;
9800 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009801
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309802 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9803 TRACE_CODE_HDD_CFG80211_STOP_AP,
9804 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309805 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9806 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309807 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009808 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309809 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009810 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009811
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009812 pScanInfo = &pHddCtx->scan_info;
9813
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309814 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9815 __func__, hdd_device_modetoString(pAdapter->device_mode),
9816 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009817
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309818 ret = wlan_hdd_scan_abort(pAdapter);
9819
Girish Gowli4bf7a632014-06-12 13:42:11 +05309820 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009821 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9823 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309824
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309825 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009826 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9828 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009829
Jeff Johnsone7245742012-09-05 17:12:55 -07009830 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309831 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009832 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309833 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009834 }
9835
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309836 /* Delete all associated STAs before stopping AP/P2P GO */
9837 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309838 hdd_hostapd_stop(dev);
9839
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 )
9843 {
9844 beacon_data_t *old;
9845
9846 old = pAdapter->sessionCtx.ap.beacon;
9847
9848 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309849 {
9850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9851 FL("session(%d) beacon data points to NULL"),
9852 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309854 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009855
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009857
9858 mutex_lock(&pHddCtx->sap_lock);
9859 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9860 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009861 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 {
9863 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9864
9865 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9866
9867 if (!VOS_IS_STATUS_SUCCESS(status))
9868 {
9869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009870 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309872 }
9873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309875 /* BSS stopped, clear the active sessions for this device mode */
9876 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 }
9878 mutex_unlock(&pHddCtx->sap_lock);
9879
9880 if(status != VOS_STATUS_SUCCESS)
9881 {
9882 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009883 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 return -EINVAL;
9885 }
9886
Jeff Johnson4416a782013-03-25 14:17:50 -07009887 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9889 ==eHAL_STATUS_FAILURE)
9890 {
9891 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009892 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 }
9894
Jeff Johnson4416a782013-03-25 14:17:50 -07009895 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9897 eANI_BOOLEAN_FALSE) )
9898 {
9899 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009900 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 }
9902
9903 // Reset WNI_CFG_PROBE_RSP Flags
9904 wlan_hdd_reset_prob_rspies(pAdapter);
9905
9906 pAdapter->sessionCtx.ap.beacon = NULL;
9907 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009908#ifdef WLAN_FEATURE_P2P_DEBUG
9909 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9910 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9911 {
9912 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9913 "GO got removed");
9914 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9915 }
9916#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 }
9918 EXIT();
9919 return status;
9920}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009921
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309922#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9923static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9924 struct net_device *dev)
9925{
9926 int ret;
9927
9928 vos_ssr_protect(__func__);
9929 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9930 vos_ssr_unprotect(__func__);
9931
9932 return ret;
9933}
9934#else
9935static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9936 struct net_device *dev)
9937{
9938 int ret;
9939
9940 vos_ssr_protect(__func__);
9941 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9942 vos_ssr_unprotect(__func__);
9943
9944 return ret;
9945}
9946#endif
9947
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009948#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9949
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309950static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309951 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009952 struct cfg80211_ap_settings *params)
9953{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309954 hdd_adapter_t *pAdapter;
9955 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309956 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009957
9958 ENTER();
9959
Girish Gowlib143d7a2015-02-18 19:39:55 +05309960 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009961 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309963 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309964 return -ENODEV;
9965 }
9966
9967 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9968 if (NULL == pAdapter)
9969 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309971 "%s: HDD adapter is Null", __func__);
9972 return -ENODEV;
9973 }
9974
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309975 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9976 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9977 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309978 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9979 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309981 "%s: HDD adapter magic is invalid", __func__);
9982 return -ENODEV;
9983 }
9984
9985 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309986 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309987 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309988 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309989 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309990 }
9991
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309992 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9993 __func__, hdd_device_modetoString(pAdapter->device_mode),
9994 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309995
9996 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009997 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009998 )
9999 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010000 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010001
10002 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010003
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010004 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010005 {
10006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10007 FL("already beacon info added to session(%d)"),
10008 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010009 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010010 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010011
Girish Gowlib143d7a2015-02-18 19:39:55 +053010012#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10013 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10014 &new,
10015 &params->beacon);
10016#else
10017 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10018 &new,
10019 &params->beacon,
10020 params->dtim_period);
10021#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010022
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010023 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010024 {
10025 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010026 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010027 return -EINVAL;
10028 }
10029 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010030#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010031 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10032#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10033 params->channel, params->channel_type);
10034#else
10035 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10036#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010037#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010038 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010039 params->ssid_len, params->hidden_ssid,
10040 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010041 }
10042
10043 EXIT();
10044 return status;
10045}
10046
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010047static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10048 struct net_device *dev,
10049 struct cfg80211_ap_settings *params)
10050{
10051 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010052
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010053 vos_ssr_protect(__func__);
10054 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10055 vos_ssr_unprotect(__func__);
10056
10057 return ret;
10058}
10059
10060static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010061 struct net_device *dev,
10062 struct cfg80211_beacon_data *params)
10063{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010065 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010066 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010067
10068 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010069
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010070 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10071 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10072 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010073 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010074 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010075
10076 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10077 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010078 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010079 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010080 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010081 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010082
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010083 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010084 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010085 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010086 {
10087 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010088
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010089 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010090
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010091 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010092 {
10093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10094 FL("session(%d) beacon data points to NULL"),
10095 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010096 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010097 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010098
10099 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10100
10101 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010103 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010104 return -EINVAL;
10105 }
10106
10107 pAdapter->sessionCtx.ap.beacon = new;
10108
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010109 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10110 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010111 }
10112
10113 EXIT();
10114 return status;
10115}
10116
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010117static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10118 struct net_device *dev,
10119 struct cfg80211_beacon_data *params)
10120{
10121 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010122
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010123 vos_ssr_protect(__func__);
10124 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10125 vos_ssr_unprotect(__func__);
10126
10127 return ret;
10128}
10129
10130#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010131
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010132static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 struct net_device *dev,
10134 struct bss_parameters *params)
10135{
10136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010137 hdd_context_t *pHddCtx;
10138 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010139
10140 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010141
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010142 if (NULL == pAdapter)
10143 {
10144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10145 "%s: HDD adapter is Null", __func__);
10146 return -ENODEV;
10147 }
10148 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010149 ret = wlan_hdd_validate_context(pHddCtx);
10150 if (0 != ret)
10151 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010152 return ret;
10153 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010154 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10155 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10156 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10158 __func__, hdd_device_modetoString(pAdapter->device_mode),
10159 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010160
10161 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010162 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010163 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010164 {
10165 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10166 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010167 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 {
10169 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010170 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 }
10172
10173 EXIT();
10174 return 0;
10175}
10176
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010177static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10178 struct net_device *dev,
10179 struct bss_parameters *params)
10180{
10181 int ret;
10182
10183 vos_ssr_protect(__func__);
10184 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10185 vos_ssr_unprotect(__func__);
10186
10187 return ret;
10188}
Kiet Lam10841362013-11-01 11:36:50 +053010189/* FUNCTION: wlan_hdd_change_country_code_cd
10190* to wait for contry code completion
10191*/
10192void* wlan_hdd_change_country_code_cb(void *pAdapter)
10193{
10194 hdd_adapter_t *call_back_pAdapter = pAdapter;
10195 complete(&call_back_pAdapter->change_country_code);
10196 return NULL;
10197}
10198
Jeff Johnson295189b2012-06-20 16:38:30 -070010199/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010200 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10202 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010203int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 struct net_device *ndev,
10205 enum nl80211_iftype type,
10206 u32 *flags,
10207 struct vif_params *params
10208 )
10209{
10210 struct wireless_dev *wdev;
10211 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010212 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010213 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010214 tCsrRoamProfile *pRoamProfile = NULL;
10215 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010216 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 eMib_dot11DesiredBssType connectedBssType;
10218 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010219 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010220
10221 ENTER();
10222
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010223 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010224 {
10225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10226 "%s: Adapter context is null", __func__);
10227 return VOS_STATUS_E_FAILURE;
10228 }
10229
10230 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10231 if (!pHddCtx)
10232 {
10233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10234 "%s: HDD context is null", __func__);
10235 return VOS_STATUS_E_FAILURE;
10236 }
10237
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010238 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10239 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10240 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010241 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010242 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010244 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010245 }
10246
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010247 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10248 __func__, hdd_device_modetoString(pAdapter->device_mode),
10249 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010250
Agarwal Ashish51325b52014-06-16 16:50:49 +053010251 if (vos_max_concurrent_connections_reached()) {
10252 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10253 return -EINVAL;
10254 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010255 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 wdev = ndev->ieee80211_ptr;
10257
10258#ifdef WLAN_BTAMP_FEATURE
10259 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10260 (NL80211_IFTYPE_ADHOC == type)||
10261 (NL80211_IFTYPE_AP == type)||
10262 (NL80211_IFTYPE_P2P_GO == type))
10263 {
10264 pHddCtx->isAmpAllowed = VOS_FALSE;
10265 // stop AMP traffic
10266 status = WLANBAP_StopAmp();
10267 if(VOS_STATUS_SUCCESS != status )
10268 {
10269 pHddCtx->isAmpAllowed = VOS_TRUE;
10270 hddLog(VOS_TRACE_LEVEL_FATAL,
10271 "%s: Failed to stop AMP", __func__);
10272 return -EINVAL;
10273 }
10274 }
10275#endif //WLAN_BTAMP_FEATURE
10276 /* Reset the current device mode bit mask*/
10277 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10278
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010279 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10280 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10281 (type == NL80211_IFTYPE_P2P_GO)))
10282 {
10283 /* Notify Mode change in case of concurrency.
10284 * Below function invokes TDLS teardown Functionality Since TDLS is
10285 * not Supported in case of concurrency i.e Once P2P session
10286 * is detected disable offchannel and teardown TDLS links
10287 */
10288 hddLog(LOG1,
10289 FL("Device mode = %d Interface type = %d"),
10290 pAdapter->device_mode, type);
10291 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10292 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010293
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010295 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010296 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 )
10298 {
10299 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010300 if (!pWextState)
10301 {
10302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10303 "%s: pWextState is null", __func__);
10304 return VOS_STATUS_E_FAILURE;
10305 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 pRoamProfile = &pWextState->roamProfile;
10307 LastBSSType = pRoamProfile->BSSType;
10308
10309 switch (type)
10310 {
10311 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 hddLog(VOS_TRACE_LEVEL_INFO,
10314 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10315 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010316#ifdef WLAN_FEATURE_11AC
10317 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10318 {
10319 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10320 }
10321#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010322 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010323 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010324 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010325 //Check for sub-string p2p to confirm its a p2p interface
10326 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010327 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010328#ifdef FEATURE_WLAN_TDLS
10329 mutex_lock(&pHddCtx->tdls_lock);
10330 wlan_hdd_tdls_exit(pAdapter, TRUE);
10331 mutex_unlock(&pHddCtx->tdls_lock);
10332#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010333 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10334 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10335 }
10336 else
10337 {
10338 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010340 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010341 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010342
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 case NL80211_IFTYPE_ADHOC:
10344 hddLog(VOS_TRACE_LEVEL_INFO,
10345 "%s: setting interface Type to ADHOC", __func__);
10346 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10347 pRoamProfile->phyMode =
10348 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010349 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010351 hdd_set_ibss_ops( pAdapter );
10352 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010353
10354 status = hdd_sta_id_hash_attach(pAdapter);
10355 if (VOS_STATUS_SUCCESS != status) {
10356 hddLog(VOS_TRACE_LEVEL_ERROR,
10357 FL("Failed to initialize hash for IBSS"));
10358 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 break;
10360
10361 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010363 {
10364 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10365 "%s: setting interface Type to %s", __func__,
10366 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10367
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010368 //Cancel any remain on channel for GO mode
10369 if (NL80211_IFTYPE_P2P_GO == type)
10370 {
10371 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10372 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010373 if (NL80211_IFTYPE_AP == type)
10374 {
10375 /* As Loading WLAN Driver one interface being created for p2p device
10376 * address. This will take one HW STA and the max number of clients
10377 * that can connect to softAP will be reduced by one. so while changing
10378 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10379 * interface as it is not required in SoftAP mode.
10380 */
10381
10382 // Get P2P Adapter
10383 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10384
10385 if (pP2pAdapter)
10386 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010387 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010388 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010389 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10390 }
10391 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010392 //Disable IMPS & BMPS for SAP/GO
10393 if(VOS_STATUS_E_FAILURE ==
10394 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10395 {
10396 //Fail to Exit BMPS
10397 VOS_ASSERT(0);
10398 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010399
10400 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10401
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010402#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010403
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010404 /* A Mutex Lock is introduced while changing the mode to
10405 * protect the concurrent access for the Adapters by TDLS
10406 * module.
10407 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010408 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010409#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010411 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010413 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10414 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010415#ifdef FEATURE_WLAN_TDLS
10416 mutex_unlock(&pHddCtx->tdls_lock);
10417#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010418 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10419 (pConfig->apRandomBssidEnabled))
10420 {
10421 /* To meet Android requirements create a randomized
10422 MAC address of the form 02:1A:11:Fx:xx:xx */
10423 get_random_bytes(&ndev->dev_addr[3], 3);
10424 ndev->dev_addr[0] = 0x02;
10425 ndev->dev_addr[1] = 0x1A;
10426 ndev->dev_addr[2] = 0x11;
10427 ndev->dev_addr[3] |= 0xF0;
10428 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10429 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010430 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10431 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010432 }
10433
Jeff Johnson295189b2012-06-20 16:38:30 -070010434 hdd_set_ap_ops( pAdapter->dev );
10435
Kiet Lam10841362013-11-01 11:36:50 +053010436 /* This is for only SAP mode where users can
10437 * control country through ini.
10438 * P2P GO follows station country code
10439 * acquired during the STA scanning. */
10440 if((NL80211_IFTYPE_AP == type) &&
10441 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10442 {
10443 int status = 0;
10444 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10445 "%s: setting country code from INI ", __func__);
10446 init_completion(&pAdapter->change_country_code);
10447 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10448 (void *)(tSmeChangeCountryCallback)
10449 wlan_hdd_change_country_code_cb,
10450 pConfig->apCntryCode, pAdapter,
10451 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010452 eSIR_FALSE,
10453 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010454 if (eHAL_STATUS_SUCCESS == status)
10455 {
10456 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010457 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010458 &pAdapter->change_country_code,
10459 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010460 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010461 {
10462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010463 FL("SME Timed out while setting country code %ld"),
10464 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010465
10466 if (pHddCtx->isLogpInProgress)
10467 {
10468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10469 "%s: LOGP in Progress. Ignore!!!", __func__);
10470 return -EAGAIN;
10471 }
Kiet Lam10841362013-11-01 11:36:50 +053010472 }
10473 }
10474 else
10475 {
10476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010477 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010478 return -EINVAL;
10479 }
10480 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 status = hdd_init_ap_mode(pAdapter);
10482 if(status != VOS_STATUS_SUCCESS)
10483 {
10484 hddLog(VOS_TRACE_LEVEL_FATAL,
10485 "%s: Error initializing the ap mode", __func__);
10486 return -EINVAL;
10487 }
10488 hdd_set_conparam(1);
10489
Nirav Shah7e3c8132015-06-22 23:51:42 +053010490 status = hdd_sta_id_hash_attach(pAdapter);
10491 if (VOS_STATUS_SUCCESS != status)
10492 {
10493 hddLog(VOS_TRACE_LEVEL_ERROR,
10494 FL("Failed to initialize hash for AP"));
10495 return -EINVAL;
10496 }
10497
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 /*interface type changed update in wiphy structure*/
10499 if(wdev)
10500 {
10501 wdev->iftype = type;
10502 pHddCtx->change_iface = type;
10503 }
10504 else
10505 {
10506 hddLog(VOS_TRACE_LEVEL_ERROR,
10507 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10508 return -EINVAL;
10509 }
10510 goto done;
10511 }
10512
10513 default:
10514 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10515 __func__);
10516 return -EOPNOTSUPP;
10517 }
10518 }
10519 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 )
10522 {
10523 switch(type)
10524 {
10525 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010528
10529 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010530#ifdef FEATURE_WLAN_TDLS
10531
10532 /* A Mutex Lock is introduced while changing the mode to
10533 * protect the concurrent access for the Adapters by TDLS
10534 * module.
10535 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010536 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010537#endif
c_hpothu002231a2015-02-05 14:58:51 +053010538 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010540 //Check for sub-string p2p to confirm its a p2p interface
10541 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010542 {
10543 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10544 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10545 }
10546 else
10547 {
10548 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010549 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010550 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010551 hdd_set_conparam(0);
10552 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010553 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10554 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010555#ifdef FEATURE_WLAN_TDLS
10556 mutex_unlock(&pHddCtx->tdls_lock);
10557#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010558 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010559 if( VOS_STATUS_SUCCESS != status )
10560 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010561 /* In case of JB, for P2P-GO, only change interface will be called,
10562 * This is the right place to enable back bmps_imps()
10563 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010564 if (pHddCtx->hdd_wlan_suspended)
10565 {
10566 hdd_set_pwrparams(pHddCtx);
10567 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010568 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 goto done;
10570 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10574 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 goto done;
10576 default:
10577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10578 __func__);
10579 return -EOPNOTSUPP;
10580
10581 }
10582
10583 }
10584 else
10585 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010586 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10587 __func__, hdd_device_modetoString(pAdapter->device_mode),
10588 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 return -EOPNOTSUPP;
10590 }
10591
10592
10593 if(pRoamProfile)
10594 {
10595 if ( LastBSSType != pRoamProfile->BSSType )
10596 {
10597 /*interface type changed update in wiphy structure*/
10598 wdev->iftype = type;
10599
10600 /*the BSS mode changed, We need to issue disconnect
10601 if connected or in IBSS disconnect state*/
10602 if ( hdd_connGetConnectedBssType(
10603 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10604 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10605 {
10606 /*need to issue a disconnect to CSR.*/
10607 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10608 if( eHAL_STATUS_SUCCESS ==
10609 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10610 pAdapter->sessionId,
10611 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10612 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010613 ret = wait_for_completion_interruptible_timeout(
10614 &pAdapter->disconnect_comp_var,
10615 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10616 if (ret <= 0)
10617 {
10618 hddLog(VOS_TRACE_LEVEL_ERROR,
10619 FL("wait on disconnect_comp_var failed %ld"), ret);
10620 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010621 }
10622 }
10623 }
10624 }
10625
10626done:
10627 /*set bitmask based on updated value*/
10628 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010629
10630 /* Only STA mode support TM now
10631 * all other mode, TM feature should be disabled */
10632 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10633 (~VOS_STA & pHddCtx->concurrency_mode) )
10634 {
10635 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10636 }
10637
Jeff Johnson295189b2012-06-20 16:38:30 -070010638#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010639 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010640 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010641 {
10642 //we are ok to do AMP
10643 pHddCtx->isAmpAllowed = VOS_TRUE;
10644 }
10645#endif //WLAN_BTAMP_FEATURE
10646 EXIT();
10647 return 0;
10648}
10649
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010650/*
10651 * FUNCTION: wlan_hdd_cfg80211_change_iface
10652 * wrapper function to protect the actual implementation from SSR.
10653 */
10654int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10655 struct net_device *ndev,
10656 enum nl80211_iftype type,
10657 u32 *flags,
10658 struct vif_params *params
10659 )
10660{
10661 int ret;
10662
10663 vos_ssr_protect(__func__);
10664 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10665 vos_ssr_unprotect(__func__);
10666
10667 return ret;
10668}
10669
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010670#ifdef FEATURE_WLAN_TDLS
10671static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010672 struct net_device *dev,
10673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10674 const u8 *mac,
10675#else
10676 u8 *mac,
10677#endif
10678 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010679{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010680 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010681 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010682 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010683 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010684 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010685 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010686
10687 ENTER();
10688
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010689 if (!dev) {
10690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10691 return -EINVAL;
10692 }
10693
10694 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10695 if (!pAdapter) {
10696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10697 return -EINVAL;
10698 }
10699
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010700 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010701 {
10702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10703 "Invalid arguments");
10704 return -EINVAL;
10705 }
Hoonki Lee27511902013-03-14 18:19:06 -070010706
10707 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10708 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10709 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010711 "%s: TDLS mode is disabled OR not enabled in FW."
10712 MAC_ADDRESS_STR " Request declined.",
10713 __func__, MAC_ADDR_ARRAY(mac));
10714 return -ENOTSUPP;
10715 }
10716
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010717 if (pHddCtx->isLogpInProgress)
10718 {
10719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10720 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010721 wlan_hdd_tdls_set_link_status(pAdapter,
10722 mac,
10723 eTDLS_LINK_IDLE,
10724 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010725 return -EBUSY;
10726 }
10727
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010728 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010729 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010730
10731 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010733 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10734 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010735 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010736 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010737 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010738
10739 /* in add station, we accept existing valid staId if there is */
10740 if ((0 == update) &&
10741 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10742 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010743 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010745 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010746 " link_status %d. staId %d. add station ignored.",
10747 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010748 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010749 return 0;
10750 }
10751 /* in change station, we accept only when staId is valid */
10752 if ((1 == update) &&
10753 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10754 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10755 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010756 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010758 "%s: " MAC_ADDRESS_STR
10759 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010760 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10761 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10762 mutex_unlock(&pHddCtx->tdls_lock);
10763 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010764 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010765 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010766
10767 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010768 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010769 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10771 "%s: " MAC_ADDRESS_STR
10772 " TDLS setup is ongoing. Request declined.",
10773 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010774 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010775 }
10776
10777 /* first to check if we reached to maximum supported TDLS peer.
10778 TODO: for now, return -EPERM looks working fine,
10779 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010780 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10781 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010782 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10784 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010785 " TDLS Max peer already connected. Request declined."
10786 " Num of peers (%d), Max allowed (%d).",
10787 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10788 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010789 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010790 }
10791 else
10792 {
10793 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010794 mutex_lock(&pHddCtx->tdls_lock);
10795 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010796 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010797 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010798 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10800 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10801 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010802 return -EPERM;
10803 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010804 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010805 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010806 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010807 wlan_hdd_tdls_set_link_status(pAdapter,
10808 mac,
10809 eTDLS_LINK_CONNECTING,
10810 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010811
Jeff Johnsond75fe012013-04-06 10:53:06 -070010812 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010813 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010814 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010816 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010817 if(StaParams->htcap_present)
10818 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010820 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010822 "ht_capa->extended_capabilities: %0x",
10823 StaParams->HTCap.extendedHtCapInfo);
10824 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010826 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010828 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010829 if(StaParams->vhtcap_present)
10830 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010832 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10833 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10834 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10835 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010836 {
10837 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010839 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010841 "[%d]: %x ", i, StaParams->supported_rates[i]);
10842 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010843 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010844 else if ((1 == update) && (NULL == StaParams))
10845 {
10846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10847 "%s : update is true, but staParams is NULL. Error!", __func__);
10848 return -EPERM;
10849 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010850
10851 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10852
10853 if (!update)
10854 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010855 /*Before adding sta make sure that device exited from BMPS*/
10856 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10857 {
10858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10859 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10860 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10861 if (status != VOS_STATUS_SUCCESS) {
10862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10863 }
10864 }
10865
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010866 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010867 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010868 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010869 hddLog(VOS_TRACE_LEVEL_ERROR,
10870 FL("Failed to add TDLS peer STA. Enable Bmps"));
10871 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010872 return -EPERM;
10873 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010874 }
10875 else
10876 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010877 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010878 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010879 if (ret != eHAL_STATUS_SUCCESS) {
10880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10881 return -EPERM;
10882 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010883 }
10884
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010885 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010886 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10887
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010888 mutex_lock(&pHddCtx->tdls_lock);
10889 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
10890
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010891 if ((pTdlsPeer != NULL) &&
10892 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010893 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010894 hddLog(VOS_TRACE_LEVEL_ERROR,
10895 FL("peer link status %u"), pTdlsPeer->link_status);
10896 mutex_unlock(&pHddCtx->tdls_lock);
10897 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010898 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010899 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010900
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010901 if (ret <= 0)
10902 {
10903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10904 "%s: timeout waiting for tdls add station indication %ld",
10905 __func__, ret);
10906 goto error;
10907 }
10908
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010909 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10910 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010912 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010913 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010914 }
10915
10916 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010917
10918error:
Atul Mittal115287b2014-07-08 13:26:33 +053010919 wlan_hdd_tdls_set_link_status(pAdapter,
10920 mac,
10921 eTDLS_LINK_IDLE,
10922 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010923 return -EPERM;
10924
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010925}
10926#endif
10927
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010928static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010930#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10931 const u8 *mac,
10932#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010934#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010935 struct station_parameters *params)
10936{
10937 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010938 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010939 hdd_context_t *pHddCtx;
10940 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010941 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010942 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010943#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010944 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010945 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010946 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053010947 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010948#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010949
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010950 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010951
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010952 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010953 if ((NULL == pAdapter))
10954 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010956 "invalid adapter ");
10957 return -EINVAL;
10958 }
10959
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010960 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10961 TRACE_CODE_HDD_CHANGE_STATION,
10962 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010963 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010964
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010965 ret = wlan_hdd_validate_context(pHddCtx);
10966 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010967 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010968 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010969 }
10970
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010971 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10972
10973 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010974 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10976 "invalid HDD station context");
10977 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010978 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10980
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010981 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10982 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010984 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010986 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 WLANTL_STA_AUTHENTICATED);
10988
Gopichand Nakkala29149562013-05-10 21:43:41 +053010989 if (status != VOS_STATUS_SUCCESS)
10990 {
10991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10992 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10993 return -EINVAL;
10994 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010995 }
10996 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010997 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10998 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010999#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011000 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11001 StaParams.capability = params->capability;
11002 StaParams.uapsd_queues = params->uapsd_queues;
11003 StaParams.max_sp = params->max_sp;
11004
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011005 /* Convert (first channel , number of channels) tuple to
11006 * the total list of channels. This goes with the assumption
11007 * that if the first channel is < 14, then the next channels
11008 * are an incremental of 1 else an incremental of 4 till the number
11009 * of channels.
11010 */
11011 if (0 != params->supported_channels_len) {
11012 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11013 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11014 {
11015 int wifi_chan_index;
11016 StaParams.supported_channels[j] = params->supported_channels[i];
11017 wifi_chan_index =
11018 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11019 no_of_channels = params->supported_channels[i+1];
11020 for(k=1; k <= no_of_channels; k++)
11021 {
11022 StaParams.supported_channels[j+1] =
11023 StaParams.supported_channels[j] + wifi_chan_index;
11024 j+=1;
11025 }
11026 }
11027 StaParams.supported_channels_len = j;
11028 }
11029 vos_mem_copy(StaParams.supported_oper_classes,
11030 params->supported_oper_classes,
11031 params->supported_oper_classes_len);
11032 StaParams.supported_oper_classes_len =
11033 params->supported_oper_classes_len;
11034
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011035 if (0 != params->ext_capab_len)
11036 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11037 sizeof(StaParams.extn_capability));
11038
11039 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011040 {
11041 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011042 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011043 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011044
11045 StaParams.supported_rates_len = params->supported_rates_len;
11046
11047 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11048 * The supported_rates array , for all the structures propogating till Add Sta
11049 * to the firmware has to be modified , if the supplicant (ieee80211) is
11050 * modified to send more rates.
11051 */
11052
11053 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11054 */
11055 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11056 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11057
11058 if (0 != StaParams.supported_rates_len) {
11059 int i = 0;
11060 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11061 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011063 "Supported Rates with Length %d", StaParams.supported_rates_len);
11064 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011066 "[%d]: %0x", i, StaParams.supported_rates[i]);
11067 }
11068
11069 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011070 {
11071 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011072 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011073 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011074
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011075 if (0 != params->ext_capab_len ) {
11076 /*Define A Macro : TODO Sunil*/
11077 if ((1<<4) & StaParams.extn_capability[3]) {
11078 isBufSta = 1;
11079 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011080 /* TDLS Channel Switching Support */
11081 if ((1<<6) & StaParams.extn_capability[3]) {
11082 isOffChannelSupported = 1;
11083 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011084 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011085
11086 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
11087 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
11088
11089 /* TDLS Peer is WME/QoS capable */
11090 isQosWmmSta = TRUE;
11091 }
11092
11093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11094 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11095 __func__, isQosWmmSta, StaParams.htcap_present);
11096
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011097 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11098 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011099 isOffChannelSupported,
11100 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011101
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011102 if (VOS_STATUS_SUCCESS != status) {
11103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11104 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11105 return -EINVAL;
11106 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011107 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11108
11109 if (VOS_STATUS_SUCCESS != status) {
11110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11111 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11112 return -EINVAL;
11113 }
11114 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011115#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011116 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011117 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011118 return status;
11119}
11120
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11122static int wlan_hdd_change_station(struct wiphy *wiphy,
11123 struct net_device *dev,
11124 const u8 *mac,
11125 struct station_parameters *params)
11126#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011127static int wlan_hdd_change_station(struct wiphy *wiphy,
11128 struct net_device *dev,
11129 u8 *mac,
11130 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011131#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011132{
11133 int ret;
11134
11135 vos_ssr_protect(__func__);
11136 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11137 vos_ssr_unprotect(__func__);
11138
11139 return ret;
11140}
11141
Jeff Johnson295189b2012-06-20 16:38:30 -070011142/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011143 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011144 * This function is used to initialize the key information
11145 */
11146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011147static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011148 struct net_device *ndev,
11149 u8 key_index, bool pairwise,
11150 const u8 *mac_addr,
11151 struct key_params *params
11152 )
11153#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011154static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 struct net_device *ndev,
11156 u8 key_index, const u8 *mac_addr,
11157 struct key_params *params
11158 )
11159#endif
11160{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 tCsrRoamSetKey setKey;
11163 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011164 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011165 v_U32_t roamId= 0xFF;
11166 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 hdd_hostapd_state_t *pHostapdState;
11168 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011169 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011170 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011171
11172 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011173
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011174 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11175 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11176 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011177 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11178 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011179 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011180 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011181 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011182 }
11183
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011184 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11185 __func__, hdd_device_modetoString(pAdapter->device_mode),
11186 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011187
11188 if (CSR_MAX_NUM_KEY <= key_index)
11189 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011190 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 key_index);
11192
11193 return -EINVAL;
11194 }
11195
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011196 if (CSR_MAX_KEY_LEN < params->key_len)
11197 {
11198 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11199 params->key_len);
11200
11201 return -EINVAL;
11202 }
11203
11204 hddLog(VOS_TRACE_LEVEL_INFO,
11205 "%s: called with key index = %d & key length %d",
11206 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011207
11208 /*extract key idx, key len and key*/
11209 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11210 setKey.keyId = key_index;
11211 setKey.keyLength = params->key_len;
11212 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11213
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011214 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 {
11216 case WLAN_CIPHER_SUITE_WEP40:
11217 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11218 break;
11219
11220 case WLAN_CIPHER_SUITE_WEP104:
11221 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11222 break;
11223
11224 case WLAN_CIPHER_SUITE_TKIP:
11225 {
11226 u8 *pKey = &setKey.Key[0];
11227 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11228
11229 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11230
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011231 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011232
11233 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011234 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 |--------------|----------|----------|
11236 <---16bytes---><--8bytes--><--8bytes-->
11237
11238 */
11239 /*Sme expects the 32 bytes key to be in the below order
11240
11241 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011242 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 |--------------|----------|----------|
11244 <---16bytes---><--8bytes--><--8bytes-->
11245 */
11246 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011247 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011248
11249 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011250 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011251
11252 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011253 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011254
11255
11256 break;
11257 }
11258
11259 case WLAN_CIPHER_SUITE_CCMP:
11260 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11261 break;
11262
11263#ifdef FEATURE_WLAN_WAPI
11264 case WLAN_CIPHER_SUITE_SMS4:
11265 {
11266 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11267 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11268 params->key, params->key_len);
11269 return 0;
11270 }
11271#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011272
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011273#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 case WLAN_CIPHER_SUITE_KRK:
11275 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11276 break;
11277#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011278
11279#ifdef WLAN_FEATURE_11W
11280 case WLAN_CIPHER_SUITE_AES_CMAC:
11281 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011282 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011283#endif
11284
Jeff Johnson295189b2012-06-20 16:38:30 -070011285 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011288 status = -EOPNOTSUPP;
11289 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 }
11291
11292 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11293 __func__, setKey.encType);
11294
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011295 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11297 (!pairwise)
11298#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011299 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011300#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011301 )
11302 {
11303 /* set group key*/
11304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11305 "%s- %d: setting Broadcast key",
11306 __func__, __LINE__);
11307 setKey.keyDirection = eSIR_RX_ONLY;
11308 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11309 }
11310 else
11311 {
11312 /* set pairwise key*/
11313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11314 "%s- %d: setting pairwise key",
11315 __func__, __LINE__);
11316 setKey.keyDirection = eSIR_TX_RX;
11317 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11318 }
11319 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11320 {
11321 setKey.keyDirection = eSIR_TX_RX;
11322 /*Set the group key*/
11323 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11324 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011325
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011326 if ( 0 != status )
11327 {
11328 hddLog(VOS_TRACE_LEVEL_ERROR,
11329 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011330 status = -EINVAL;
11331 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011332 }
11333 /*Save the keys here and call sme_RoamSetKey for setting
11334 the PTK after peer joins the IBSS network*/
11335 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11336 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011337 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011338 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011339 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11340 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11341 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011343 if( pHostapdState->bssState == BSS_START )
11344 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011345 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11346 vos_status = wlan_hdd_check_ula_done(pAdapter);
11347
11348 if ( vos_status != VOS_STATUS_SUCCESS )
11349 {
11350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11351 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11352 __LINE__, vos_status );
11353
11354 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11355
11356 status = -EINVAL;
11357 goto end;
11358 }
11359
Jeff Johnson295189b2012-06-20 16:38:30 -070011360 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11361
11362 if ( status != eHAL_STATUS_SUCCESS )
11363 {
11364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11365 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11366 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011367 status = -EINVAL;
11368 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011369 }
11370 }
11371
11372 /* Saving WEP keys */
11373 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11374 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11375 {
11376 //Save the wep key in ap context. Issue setkey after the BSS is started.
11377 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11378 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11379 }
11380 else
11381 {
11382 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011383 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11385 }
11386 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011387 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11388 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011389 {
11390 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11391 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11392
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011393#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11394 if (!pairwise)
11395#else
11396 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11397#endif
11398 {
11399 /* set group key*/
11400 if (pHddStaCtx->roam_info.deferKeyComplete)
11401 {
11402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11403 "%s- %d: Perform Set key Complete",
11404 __func__, __LINE__);
11405 hdd_PerformRoamSetKeyComplete(pAdapter);
11406 }
11407 }
11408
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11410
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011411 pWextState->roamProfile.Keys.defaultIndex = key_index;
11412
11413
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011414 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 params->key, params->key_len);
11416
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011417
Jeff Johnson295189b2012-06-20 16:38:30 -070011418 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11419
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011420 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011422 __func__, setKey.peerMac[0], setKey.peerMac[1],
11423 setKey.peerMac[2], setKey.peerMac[3],
11424 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 setKey.keyDirection);
11426
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011427 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011428
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011429 if ( vos_status != VOS_STATUS_SUCCESS )
11430 {
11431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11433 __LINE__, vos_status );
11434
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011435 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011436
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011437 status = -EINVAL;
11438 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011439
11440 }
11441
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011442#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011443 /* The supplicant may attempt to set the PTK once pre-authentication
11444 is done. Save the key in the UMAC and include it in the ADD BSS
11445 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011446 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011447 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011448 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011449 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11450 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011451 status = 0;
11452 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011453 }
11454 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11455 {
11456 hddLog(VOS_TRACE_LEVEL_ERROR,
11457 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011458 status = -EINVAL;
11459 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011460 }
11461#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011462
11463 /* issue set key request to SME*/
11464 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11465 pAdapter->sessionId, &setKey, &roamId );
11466
11467 if ( 0 != status )
11468 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011469 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11471 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011472 status = -EINVAL;
11473 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 }
11475
11476
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011477 /* in case of IBSS as there was no information available about WEP keys during
11478 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011480 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11481 !( ( IW_AUTH_KEY_MGMT_802_1X
11482 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11484 )
11485 &&
11486 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11487 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11488 )
11489 )
11490 {
11491 setKey.keyDirection = eSIR_RX_ONLY;
11492 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11493
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011494 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496 __func__, setKey.peerMac[0], setKey.peerMac[1],
11497 setKey.peerMac[2], setKey.peerMac[3],
11498 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 setKey.keyDirection);
11500
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011501 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 pAdapter->sessionId, &setKey, &roamId );
11503
11504 if ( 0 != status )
11505 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011506 hddLog(VOS_TRACE_LEVEL_ERROR,
11507 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 __func__, status);
11509 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011510 status = -EINVAL;
11511 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 }
11513 }
11514 }
11515
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011516end:
11517 /* Need to clear any trace of key value in the memory.
11518 * Thus zero out the memory even though it is local
11519 * variable.
11520 */
11521 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011522 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011523 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011524}
11525
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011526#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11527static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11528 struct net_device *ndev,
11529 u8 key_index, bool pairwise,
11530 const u8 *mac_addr,
11531 struct key_params *params
11532 )
11533#else
11534static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11535 struct net_device *ndev,
11536 u8 key_index, const u8 *mac_addr,
11537 struct key_params *params
11538 )
11539#endif
11540{
11541 int ret;
11542 vos_ssr_protect(__func__);
11543#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11544 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11545 mac_addr, params);
11546#else
11547 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11548 params);
11549#endif
11550 vos_ssr_unprotect(__func__);
11551
11552 return ret;
11553}
11554
Jeff Johnson295189b2012-06-20 16:38:30 -070011555/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011556 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 * This function is used to get the key information
11558 */
11559#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011560static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011561 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011562 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011563 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011564 const u8 *mac_addr, void *cookie,
11565 void (*callback)(void *cookie, struct key_params*)
11566 )
11567#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011568static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011569 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011570 struct net_device *ndev,
11571 u8 key_index, const u8 *mac_addr, void *cookie,
11572 void (*callback)(void *cookie, struct key_params*)
11573 )
11574#endif
11575{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011577 hdd_wext_state_t *pWextState = NULL;
11578 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011580 hdd_context_t *pHddCtx;
11581 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011582
11583 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011585 if (NULL == pAdapter)
11586 {
11587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11588 "%s: HDD adapter is Null", __func__);
11589 return -ENODEV;
11590 }
11591
11592 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11593 ret = wlan_hdd_validate_context(pHddCtx);
11594 if (0 != ret)
11595 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011596 return ret;
11597 }
11598
11599 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11600 pRoamProfile = &(pWextState->roamProfile);
11601
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011602 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11603 __func__, hdd_device_modetoString(pAdapter->device_mode),
11604 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011605
Jeff Johnson295189b2012-06-20 16:38:30 -070011606 memset(&params, 0, sizeof(params));
11607
11608 if (CSR_MAX_NUM_KEY <= key_index)
11609 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011611 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011612 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011613
11614 switch(pRoamProfile->EncryptionType.encryptionType[0])
11615 {
11616 case eCSR_ENCRYPT_TYPE_NONE:
11617 params.cipher = IW_AUTH_CIPHER_NONE;
11618 break;
11619
11620 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11621 case eCSR_ENCRYPT_TYPE_WEP40:
11622 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11623 break;
11624
11625 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11626 case eCSR_ENCRYPT_TYPE_WEP104:
11627 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11628 break;
11629
11630 case eCSR_ENCRYPT_TYPE_TKIP:
11631 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11632 break;
11633
11634 case eCSR_ENCRYPT_TYPE_AES:
11635 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11636 break;
11637
11638 default:
11639 params.cipher = IW_AUTH_CIPHER_NONE;
11640 break;
11641 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011642
c_hpothuaaf19692014-05-17 17:01:48 +053011643 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11644 TRACE_CODE_HDD_CFG80211_GET_KEY,
11645 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011646
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11648 params.seq_len = 0;
11649 params.seq = NULL;
11650 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11651 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011652 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 return 0;
11654}
11655
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11657static int wlan_hdd_cfg80211_get_key(
11658 struct wiphy *wiphy,
11659 struct net_device *ndev,
11660 u8 key_index, bool pairwise,
11661 const u8 *mac_addr, void *cookie,
11662 void (*callback)(void *cookie, struct key_params*)
11663 )
11664#else
11665static int wlan_hdd_cfg80211_get_key(
11666 struct wiphy *wiphy,
11667 struct net_device *ndev,
11668 u8 key_index, const u8 *mac_addr, void *cookie,
11669 void (*callback)(void *cookie, struct key_params*)
11670 )
11671#endif
11672{
11673 int ret;
11674
11675 vos_ssr_protect(__func__);
11676#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11677 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11678 mac_addr, cookie, callback);
11679#else
11680 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11681 callback);
11682#endif
11683 vos_ssr_unprotect(__func__);
11684
11685 return ret;
11686}
11687
Jeff Johnson295189b2012-06-20 16:38:30 -070011688/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011689 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 * This function is used to delete the key information
11691 */
11692#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011693static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695 u8 key_index,
11696 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 const u8 *mac_addr
11698 )
11699#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011700static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011701 struct net_device *ndev,
11702 u8 key_index,
11703 const u8 *mac_addr
11704 )
11705#endif
11706{
11707 int status = 0;
11708
11709 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011710 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 //it is observed that this is invalidating peer
11712 //key index whenever re-key is done. This is affecting data link.
11713 //It should be ok to ignore del_key.
11714#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11716 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11718 tCsrRoamSetKey setKey;
11719 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011720
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 ENTER();
11722
11723 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11724 __func__,pAdapter->device_mode);
11725
11726 if (CSR_MAX_NUM_KEY <= key_index)
11727 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 key_index);
11730
11731 return -EINVAL;
11732 }
11733
11734 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11735 setKey.keyId = key_index;
11736
11737 if (mac_addr)
11738 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11739 else
11740 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11741
11742 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11743
11744 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011746 )
11747 {
11748
11749 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11751 if( pHostapdState->bssState == BSS_START)
11752 {
11753 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011754
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 if ( status != eHAL_STATUS_SUCCESS )
11756 {
11757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11758 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11759 __LINE__, status );
11760 }
11761 }
11762 }
11763 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011764 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011765 )
11766 {
11767 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11768
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011769 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11770
11771 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011773 __func__, setKey.peerMac[0], setKey.peerMac[1],
11774 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011776 if(pAdapter->sessionCtx.station.conn_info.connState ==
11777 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011778 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011779 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011781
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 if ( 0 != status )
11783 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011784 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 "%s: sme_RoamSetKey failure, returned %d",
11786 __func__, status);
11787 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11788 return -EINVAL;
11789 }
11790 }
11791 }
11792#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011793 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011794 return status;
11795}
11796
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11798static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11799 struct net_device *ndev,
11800 u8 key_index,
11801 bool pairwise,
11802 const u8 *mac_addr
11803 )
11804#else
11805static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11806 struct net_device *ndev,
11807 u8 key_index,
11808 const u8 *mac_addr
11809 )
11810#endif
11811{
11812 int ret;
11813
11814 vos_ssr_protect(__func__);
11815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11816 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11817 mac_addr);
11818#else
11819 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11820#endif
11821 vos_ssr_unprotect(__func__);
11822
11823 return ret;
11824}
11825
Jeff Johnson295189b2012-06-20 16:38:30 -070011826/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011827 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 * This function is used to set the default tx key index
11829 */
11830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011831static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011832 struct net_device *ndev,
11833 u8 key_index,
11834 bool unicast, bool multicast)
11835#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011836static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 struct net_device *ndev,
11838 u8 key_index)
11839#endif
11840{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011842 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011843 hdd_wext_state_t *pWextState;
11844 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011845 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011846
11847 ENTER();
11848
Gopichand Nakkala29149562013-05-10 21:43:41 +053011849 if ((NULL == pAdapter))
11850 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011852 "invalid adapter");
11853 return -EINVAL;
11854 }
11855
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011856 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11857 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11858 pAdapter->sessionId, key_index));
11859
Gopichand Nakkala29149562013-05-10 21:43:41 +053011860 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11861 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11862
11863 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11864 {
11865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11866 "invalid Wext state or HDD context");
11867 return -EINVAL;
11868 }
11869
Arif Hussain6d2a3322013-11-17 19:50:10 -080011870 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011871 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011872
Jeff Johnson295189b2012-06-20 16:38:30 -070011873 if (CSR_MAX_NUM_KEY <= key_index)
11874 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011876 key_index);
11877
11878 return -EINVAL;
11879 }
11880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011881 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11882 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011883 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011884 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011885 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011886 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011887
Jeff Johnson295189b2012-06-20 16:38:30 -070011888 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011889 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011890 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011892 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011893 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011894 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011895 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011897 {
11898 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011899 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011900
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 tCsrRoamSetKey setKey;
11902 v_U32_t roamId= 0xFF;
11903 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011904
11905 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011906 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011907
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 Keys->defaultIndex = (u8)key_index;
11909 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11910 setKey.keyId = key_index;
11911 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011912
11913 vos_mem_copy(&setKey.Key[0],
11914 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011915 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011916
Gopichand Nakkala29149562013-05-10 21:43:41 +053011917 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011918
11919 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 &pHddStaCtx->conn_info.bssId[0],
11921 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011922
Gopichand Nakkala29149562013-05-10 21:43:41 +053011923 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11924 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11925 eCSR_ENCRYPT_TYPE_WEP104)
11926 {
11927 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11928 even though ap is configured for WEP-40 encryption. In this canse the key length
11929 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11930 type(104) and switching encryption type to 40*/
11931 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11932 eCSR_ENCRYPT_TYPE_WEP40;
11933 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11934 eCSR_ENCRYPT_TYPE_WEP40;
11935 }
11936
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011937 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011939
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011941 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011942 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011943
Jeff Johnson295189b2012-06-20 16:38:30 -070011944 if ( 0 != status )
11945 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011946 hddLog(VOS_TRACE_LEVEL_ERROR,
11947 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 status);
11949 return -EINVAL;
11950 }
11951 }
11952 }
11953
11954 /* In SoftAp mode setting key direction for default mode */
11955 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11956 {
11957 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11958 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11959 (eCSR_ENCRYPT_TYPE_AES !=
11960 pWextState->roamProfile.EncryptionType.encryptionType[0])
11961 )
11962 {
11963 /* Saving key direction for default key index to TX default */
11964 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11965 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11966 }
11967 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011968 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011969 return status;
11970}
11971
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11973static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11974 struct net_device *ndev,
11975 u8 key_index,
11976 bool unicast, bool multicast)
11977#else
11978static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11979 struct net_device *ndev,
11980 u8 key_index)
11981#endif
11982{
11983 int ret;
11984 vos_ssr_protect(__func__);
11985#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11986 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11987 multicast);
11988#else
11989 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11990#endif
11991 vos_ssr_unprotect(__func__);
11992
11993 return ret;
11994}
11995
Jeff Johnson295189b2012-06-20 16:38:30 -070011996/*
11997 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11998 * This function is used to inform the BSS details to nl80211 interface.
11999 */
12000static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12001 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12002{
12003 struct net_device *dev = pAdapter->dev;
12004 struct wireless_dev *wdev = dev->ieee80211_ptr;
12005 struct wiphy *wiphy = wdev->wiphy;
12006 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12007 int chan_no;
12008 int ie_length;
12009 const char *ie;
12010 unsigned int freq;
12011 struct ieee80211_channel *chan;
12012 int rssi = 0;
12013 struct cfg80211_bss *bss = NULL;
12014
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 if( NULL == pBssDesc )
12016 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012017 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 return bss;
12019 }
12020
12021 chan_no = pBssDesc->channelId;
12022 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12023 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12024
12025 if( NULL == ie )
12026 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012027 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012028 return bss;
12029 }
12030
12031#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12032 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12033 {
12034 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12035 }
12036 else
12037 {
12038 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12039 }
12040#else
12041 freq = ieee80211_channel_to_frequency(chan_no);
12042#endif
12043
12044 chan = __ieee80211_get_channel(wiphy, freq);
12045
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012046 if (!chan) {
12047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12048 return NULL;
12049 }
12050
Abhishek Singhaee43942014-06-16 18:55:47 +053012051 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012052
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012053 return cfg80211_inform_bss(wiphy, chan,
12054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12055 CFG80211_BSS_FTYPE_UNKNOWN,
12056#endif
12057 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012058 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 pBssDesc->capabilityInfo,
12060 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012061 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012062}
12063
12064
12065
12066/*
12067 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12068 * This function is used to inform the BSS details to nl80211 interface.
12069 */
12070struct cfg80211_bss*
12071wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12072 tSirBssDescription *bss_desc
12073 )
12074{
12075 /*
12076 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12077 already exists in bss data base of cfg80211 for that particular BSS ID.
12078 Using cfg80211_inform_bss_frame to update the bss entry instead of
12079 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12080 now there is no possibility to get the mgmt(probe response) frame from PE,
12081 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12082 cfg80211_inform_bss_frame.
12083 */
12084 struct net_device *dev = pAdapter->dev;
12085 struct wireless_dev *wdev = dev->ieee80211_ptr;
12086 struct wiphy *wiphy = wdev->wiphy;
12087 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012088#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12089 qcom_ie_age *qie_age = NULL;
12090 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12091#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012093#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 const char *ie =
12095 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12096 unsigned int freq;
12097 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012098 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012099 struct cfg80211_bss *bss_status = NULL;
12100 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12101 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012102 hdd_context_t *pHddCtx;
12103 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012104#ifdef WLAN_OPEN_SOURCE
12105 struct timespec ts;
12106#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012107
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012108
Wilson Yangf80a0542013-10-07 13:02:37 -070012109 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12110 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012111 if (0 != status)
12112 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012113 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012114 }
12115
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012116 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012117 if (!mgmt)
12118 {
12119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12120 "%s: memory allocation failed ", __func__);
12121 return NULL;
12122 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012123
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012125
12126#ifdef WLAN_OPEN_SOURCE
12127 /* Android does not want the timestamp from the frame.
12128 Instead it wants a monotonic increasing value */
12129 get_monotonic_boottime(&ts);
12130 mgmt->u.probe_resp.timestamp =
12131 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12132#else
12133 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12135 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012136
12137#endif
12138
Jeff Johnson295189b2012-06-20 16:38:30 -070012139 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12140 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012141
12142#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12143 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12144 /* Assuming this is the last IE, copy at the end */
12145 ie_length -=sizeof(qcom_ie_age);
12146 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12147 qie_age->element_id = QCOM_VENDOR_IE_ID;
12148 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12149 qie_age->oui_1 = QCOM_OUI1;
12150 qie_age->oui_2 = QCOM_OUI2;
12151 qie_age->oui_3 = QCOM_OUI3;
12152 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Deepthi Gowri4480a3f2016-05-18 19:30:17 +053012153 qie_age->age = vos_timer_get_system_time() - bss_desc->nReceivedTime;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012154#endif
12155
Jeff Johnson295189b2012-06-20 16:38:30 -070012156 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012157 if (bss_desc->fProbeRsp)
12158 {
12159 mgmt->frame_control |=
12160 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12161 }
12162 else
12163 {
12164 mgmt->frame_control |=
12165 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12166 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012167
12168#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012169 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012170 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12171 {
12172 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12173 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012174 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12176
12177 {
12178 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12179 }
12180 else
12181 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12183 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 kfree(mgmt);
12185 return NULL;
12186 }
12187#else
12188 freq = ieee80211_channel_to_frequency(chan_no);
12189#endif
12190 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012191 /*when the band is changed on the fly using the GUI, three things are done
12192 * 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)
12193 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12194 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12195 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12196 * and discards the channels correponding to previous band and calls back with zero bss results.
12197 * 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
12198 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12199 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12200 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12201 * So drop the bss and continue to next bss.
12202 */
12203 if(chan == NULL)
12204 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012205 hddLog(VOS_TRACE_LEVEL_ERROR,
12206 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12207 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012208 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012209 return NULL;
12210 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012211 /*To keep the rssi icon of the connected AP in the scan window
12212 *and the rssi icon of the wireless networks in sync
12213 * */
12214 if (( eConnectionState_Associated ==
12215 pAdapter->sessionCtx.station.conn_info.connState ) &&
12216 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12217 pAdapter->sessionCtx.station.conn_info.bssId,
12218 WNI_CFG_BSSID_LEN)) &&
12219 (pHddCtx->hdd_wlan_suspended == FALSE))
12220 {
12221 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12222 rssi = (pAdapter->rssi * 100);
12223 }
12224 else
12225 {
12226 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12227 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012228
Nirav Shah20ac06f2013-12-12 18:14:06 +053012229 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012230 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12231 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012232
Jeff Johnson295189b2012-06-20 16:38:30 -070012233 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12234 frame_len, rssi, GFP_KERNEL);
12235 kfree(mgmt);
12236 return bss_status;
12237}
12238
12239/*
12240 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12241 * This function is used to update the BSS data base of CFG8011
12242 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012243struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012244 tCsrRoamInfo *pRoamInfo
12245 )
12246{
12247 tCsrRoamConnectedProfile roamProfile;
12248 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12249 struct cfg80211_bss *bss = NULL;
12250
12251 ENTER();
12252
12253 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12254 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12255
12256 if (NULL != roamProfile.pBssDesc)
12257 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012258 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12259 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012260
12261 if (NULL == bss)
12262 {
12263 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12264 __func__);
12265 }
12266
12267 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12268 }
12269 else
12270 {
12271 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12272 __func__);
12273 }
12274 return bss;
12275}
12276
12277/*
12278 * FUNCTION: wlan_hdd_cfg80211_update_bss
12279 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012280static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12281 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012283{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012284 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 tCsrScanResultInfo *pScanResult;
12286 eHalStatus status = 0;
12287 tScanResultHandle pResult;
12288 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012289 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012290 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012291 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012292
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012293 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12294 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12295 NO_SESSION, pAdapter->sessionId));
12296
Wilson Yangf80a0542013-10-07 13:02:37 -070012297 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12298
12299 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12302 "%s:LOGP in Progress. Ignore!!!",__func__);
12303 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012304 }
12305
Wilson Yangf80a0542013-10-07 13:02:37 -070012306
12307 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012308 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012309 {
12310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12311 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12312 return VOS_STATUS_E_PERM;
12313 }
12314
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012315 if (pAdapter->request != NULL)
12316 {
12317 if ((pAdapter->request->n_ssids == 1)
12318 && (pAdapter->request->ssids != NULL)
12319 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12320 is_p2p_scan = true;
12321 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012322 /*
12323 * start getting scan results and populate cgf80211 BSS database
12324 */
12325 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12326
12327 /* no scan results */
12328 if (NULL == pResult)
12329 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12331 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012332 wlan_hdd_get_frame_logs(pAdapter,
12333 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 return status;
12335 }
12336
12337 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12338
12339 while (pScanResult)
12340 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012341 /*
12342 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12343 * entry already exists in bss data base of cfg80211 for that
12344 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12345 * bss entry instead of cfg80211_inform_bss, But this call expects
12346 * mgmt packet as input. As of now there is no possibility to get
12347 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012348 * ieee80211_mgmt(probe response) and passing to c
12349 * fg80211_inform_bss_frame.
12350 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012351 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12352 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12353 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012354 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12355 continue; //Skip the non p2p bss entries
12356 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012357 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12358 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012359
Jeff Johnson295189b2012-06-20 16:38:30 -070012360
12361 if (NULL == bss_status)
12362 {
12363 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012364 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 }
12366 else
12367 {
Yue Maf49ba872013-08-19 12:04:25 -070012368 cfg80211_put_bss(
12369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12370 wiphy,
12371#endif
12372 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012373 }
12374
12375 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12376 }
12377
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012378 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012379 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012380 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012381}
12382
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012383void
12384hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12385{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012386 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012387 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012388} /****** end hddPrintMacAddr() ******/
12389
12390void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012391hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012392{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012393 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012394 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012395 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12396 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12397 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012398} /****** end hddPrintPmkId() ******/
12399
12400//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12401//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12402
12403//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12404//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12405
12406#define dump_bssid(bssid) \
12407 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012408 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12409 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012410 }
12411
12412#define dump_pmkid(pMac, pmkid) \
12413 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012414 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12415 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012416 }
12417
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012418#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012419/*
12420 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12421 * This function is used to notify the supplicant of a new PMKSA candidate.
12422 */
12423int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012424 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012425 int index, bool preauth )
12426{
Jeff Johnsone7245742012-09-05 17:12:55 -070012427#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012428 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012429 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012430
12431 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012432 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012433
12434 if( NULL == pRoamInfo )
12435 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012436 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012437 return -EINVAL;
12438 }
12439
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012440 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12441 {
12442 dump_bssid(pRoamInfo->bssid);
12443 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012444 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012445 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012446#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012447 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012448}
12449#endif //FEATURE_WLAN_LFR
12450
Yue Maef608272013-04-08 23:09:17 -070012451#ifdef FEATURE_WLAN_LFR_METRICS
12452/*
12453 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12454 * 802.11r/LFR metrics reporting function to report preauth initiation
12455 *
12456 */
12457#define MAX_LFR_METRICS_EVENT_LENGTH 100
12458VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12459 tCsrRoamInfo *pRoamInfo)
12460{
12461 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12462 union iwreq_data wrqu;
12463
12464 ENTER();
12465
12466 if (NULL == pAdapter)
12467 {
12468 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12469 return VOS_STATUS_E_FAILURE;
12470 }
12471
12472 /* create the event */
12473 memset(&wrqu, 0, sizeof(wrqu));
12474 memset(metrics_notification, 0, sizeof(metrics_notification));
12475
12476 wrqu.data.pointer = metrics_notification;
12477 wrqu.data.length = scnprintf(metrics_notification,
12478 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12479 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12480
12481 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12482
12483 EXIT();
12484
12485 return VOS_STATUS_SUCCESS;
12486}
12487
12488/*
12489 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12490 * 802.11r/LFR metrics reporting function to report preauth completion
12491 * or failure
12492 */
12493VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12494 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12495{
12496 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12497 union iwreq_data wrqu;
12498
12499 ENTER();
12500
12501 if (NULL == pAdapter)
12502 {
12503 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12504 return VOS_STATUS_E_FAILURE;
12505 }
12506
12507 /* create the event */
12508 memset(&wrqu, 0, sizeof(wrqu));
12509 memset(metrics_notification, 0, sizeof(metrics_notification));
12510
12511 scnprintf(metrics_notification, sizeof(metrics_notification),
12512 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12513 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12514
12515 if (1 == preauth_status)
12516 strncat(metrics_notification, " TRUE", 5);
12517 else
12518 strncat(metrics_notification, " FALSE", 6);
12519
12520 wrqu.data.pointer = metrics_notification;
12521 wrqu.data.length = strlen(metrics_notification);
12522
12523 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12524
12525 EXIT();
12526
12527 return VOS_STATUS_SUCCESS;
12528}
12529
12530/*
12531 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12532 * 802.11r/LFR metrics reporting function to report handover initiation
12533 *
12534 */
12535VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12536 tCsrRoamInfo *pRoamInfo)
12537{
12538 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12539 union iwreq_data wrqu;
12540
12541 ENTER();
12542
12543 if (NULL == pAdapter)
12544 {
12545 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12546 return VOS_STATUS_E_FAILURE;
12547 }
12548
12549 /* create the event */
12550 memset(&wrqu, 0, sizeof(wrqu));
12551 memset(metrics_notification, 0, sizeof(metrics_notification));
12552
12553 wrqu.data.pointer = metrics_notification;
12554 wrqu.data.length = scnprintf(metrics_notification,
12555 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12556 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12557
12558 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12559
12560 EXIT();
12561
12562 return VOS_STATUS_SUCCESS;
12563}
12564#endif
12565
Jeff Johnson295189b2012-06-20 16:38:30 -070012566/*
12567 * FUNCTION: hdd_cfg80211_scan_done_callback
12568 * scanning callback function, called after finishing scan
12569 *
12570 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012571static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012572 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12573{
12574 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012575 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012577 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 struct cfg80211_scan_request *req = NULL;
12579 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012580 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012581 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012582 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012583 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012584
12585 ENTER();
12586
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012587 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012588 if (NULL == pHddCtx) {
12589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012590 goto allow_suspend;
12591 }
12592
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12594 if (!(pAdapter->dev->flags & IFF_UP))
12595 {
12596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
12597 goto allow_suspend;
12598 }
12599#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012600 pScanInfo = &pHddCtx->scan_info;
12601
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 hddLog(VOS_TRACE_LEVEL_INFO,
12603 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012604 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012605 __func__, halHandle, pContext, (int) scanId, (int) status);
12606
Kiet Lamac06e2c2013-10-23 16:25:07 +053012607 pScanInfo->mScanPendingCounter = 0;
12608
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012610 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 &pScanInfo->scan_req_completion_event,
12612 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012613 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012614 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012615 hddLog(VOS_TRACE_LEVEL_ERROR,
12616 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012617 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012618 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 }
12620
Yue Maef608272013-04-08 23:09:17 -070012621 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 {
12623 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012624 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012625 }
12626
12627 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012628 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 {
12630 hddLog(VOS_TRACE_LEVEL_INFO,
12631 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012632 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 (int) scanId);
12634 }
12635
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012636 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012637 pAdapter);
12638
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012639 if (0 > ret) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012640 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012641#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12642 goto allow_suspend;
12643#endif
12644 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012645
12646
12647 /* If any client wait scan result through WEXT
12648 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012649 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 {
12651 /* The other scan request waiting for current scan finish
12652 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012653 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012655 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012656 }
12657 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012658 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012659 {
12660 struct net_device *dev = pAdapter->dev;
12661 union iwreq_data wrqu;
12662 int we_event;
12663 char *msg;
12664
12665 memset(&wrqu, '\0', sizeof(wrqu));
12666 we_event = SIOCGIWSCAN;
12667 msg = NULL;
12668 wireless_send_event(dev, we_event, &wrqu, msg);
12669 }
12670 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012671 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012672
12673 /* Get the Scan Req */
12674 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012675 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012676
mukul sharmae7041822015-12-03 15:09:21 +053012677 if (!req || req->wiphy == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012679 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012680 pScanInfo->mScanPending = VOS_FALSE;
mukul sharmae7041822015-12-03 15:09:21 +053012681 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012682 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 }
12684
Jeff Johnson295189b2012-06-20 16:38:30 -070012685 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012686 /* Scan is no longer pending */
12687 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012688
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012689 /* last_scan_timestamp is used to decide if new scan
12690 * is needed or not on station interface. If last station
12691 * scan time and new station scan time is less then
12692 * last_scan_timestamp ; driver will return cached scan.
12693 */
12694 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12695 {
12696 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12697
12698 if ( req->n_channels )
12699 {
12700 for (i = 0; i < req->n_channels ; i++ )
12701 {
12702 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12703 }
12704 /* store no of channel scanned */
12705 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12706 }
12707
12708 }
12709
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012710 /*
12711 * cfg80211_scan_done informing NL80211 about completion
12712 * of scanning
12713 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012714 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12715 {
12716 aborted = true;
12717 }
mukul sharmae7041822015-12-03 15:09:21 +053012718
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012719 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012720
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012721 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012722
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012723 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12724 ) && (pHddCtx->spoofMacAddr.isEnabled
12725 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012726 /* Generate new random mac addr for next scan */
12727 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012728
12729 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12730 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012731 }
12732
Jeff Johnsone7245742012-09-05 17:12:55 -070012733allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012734 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012735 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012736
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012737 /* Acquire wakelock to handle the case where APP's tries to suspend
12738 * immediatly after the driver gets connect request(i.e after scan)
12739 * from supplicant, this result in app's is suspending and not able
12740 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012741 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012742
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012743#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012744 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012745#endif
12746
Jeff Johnson295189b2012-06-20 16:38:30 -070012747 EXIT();
12748 return 0;
12749}
12750
12751/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012752 * FUNCTION: hdd_isConnectionInProgress
12753 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012754 *
12755 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012756v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012757{
12758 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12759 hdd_station_ctx_t *pHddStaCtx = NULL;
12760 hdd_adapter_t *pAdapter = NULL;
12761 VOS_STATUS status = 0;
12762 v_U8_t staId = 0;
12763 v_U8_t *staMac = NULL;
12764
c_hpothu9b781ba2013-12-30 20:57:45 +053012765 if (TRUE == pHddCtx->btCoexModeSet)
12766 {
12767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012768 FL("BTCoex Mode operation in progress"));
12769 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012770 }
12771
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012772 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12773
12774 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12775 {
12776 pAdapter = pAdapterNode->pAdapter;
12777
12778 if( pAdapter )
12779 {
12780 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012781 "%s: Adapter with device mode %s (%d) exists",
12782 __func__, hdd_device_modetoString(pAdapter->device_mode),
12783 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012784 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012785 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12786 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12787 (eConnectionState_Connecting ==
12788 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12789 {
12790 hddLog(VOS_TRACE_LEVEL_ERROR,
12791 "%s: %p(%d) Connection is in progress", __func__,
12792 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12793 return VOS_TRUE;
12794 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012795 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012796 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012797 {
12798 hddLog(VOS_TRACE_LEVEL_ERROR,
12799 "%s: %p(%d) Reassociation is in progress", __func__,
12800 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12801 return VOS_TRUE;
12802 }
12803 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012804 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12805 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012806 {
12807 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12808 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012809 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012810 {
12811 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12812 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012813 "%s: client " MAC_ADDRESS_STR
12814 " is in the middle of WPS/EAPOL exchange.", __func__,
12815 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012816 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012817 }
12818 }
12819 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12820 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12821 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012822 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12823 ptSapContext pSapCtx = NULL;
12824 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12825 if(pSapCtx == NULL){
12826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12827 FL("psapCtx is NULL"));
12828 return VOS_FALSE;
12829 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012830 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12831 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012832 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12833 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012834 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012835 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012836
12837 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012838 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12839 "middle of WPS/EAPOL exchange.", __func__,
12840 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012841 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012842 }
12843 }
12844 }
12845 }
12846 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12847 pAdapterNode = pNext;
12848 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012849 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012850}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012851
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053012852/**
12853 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
12854 * to the Scan request
12855 * @scanRequest: Pointer to the csr scan request
12856 * @request: Pointer to the scan request from supplicant
12857 *
12858 * Return: None
12859 */
12860#ifdef CFG80211_SCAN_BSSID
12861static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12862 struct cfg80211_scan_request *request)
12863{
12864 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
12865}
12866#else
12867static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12868 struct cfg80211_scan_request *request)
12869{
12870}
12871#endif
12872
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012873/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012874 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 * this scan respond to scan trigger and update cfg80211 scan database
12876 * later, scan dump command can be used to recieve scan results
12877 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012878int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012879#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12880 struct net_device *dev,
12881#endif
12882 struct cfg80211_scan_request *request)
12883{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012884 hdd_adapter_t *pAdapter = NULL;
12885 hdd_context_t *pHddCtx = NULL;
12886 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012887 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012888 tCsrScanRequest scanRequest;
12889 tANI_U8 *channelList = NULL, i;
12890 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012891 int status;
12892 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012894 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012895 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012896 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012897 v_S7_t rssi=0;
12898 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012899
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12901 struct net_device *dev = NULL;
12902 if (NULL == request)
12903 {
12904 hddLog(VOS_TRACE_LEVEL_ERROR,
12905 "%s: scan req param null", __func__);
12906 return -EINVAL;
12907 }
12908 dev = request->wdev->netdev;
12909#endif
12910
12911 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12912 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12913 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12914
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 ENTER();
12916
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012917 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12918 __func__, hdd_device_modetoString(pAdapter->device_mode),
12919 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012920
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012921 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012922 if (0 != status)
12923 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012924 return status;
12925 }
12926
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012927 if (NULL == pwextBuf)
12928 {
12929 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12930 __func__);
12931 return -EIO;
12932 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012933 cfg_param = pHddCtx->cfg_ini;
12934 pScanInfo = &pHddCtx->scan_info;
12935
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012936 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12937 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12938 {
12939 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12940 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12941 }
12942
Jeff Johnson295189b2012-06-20 16:38:30 -070012943#ifdef WLAN_BTAMP_FEATURE
12944 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012945 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012946 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012947 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012948 "%s: No scanning when AMP is on", __func__);
12949 return -EOPNOTSUPP;
12950 }
12951#endif
12952 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012953 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012954 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012955 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012956 "%s: Not scanning on device_mode = %s (%d)",
12957 __func__, hdd_device_modetoString(pAdapter->device_mode),
12958 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012959 return -EOPNOTSUPP;
12960 }
12961
12962 if (TRUE == pScanInfo->mScanPending)
12963 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012964 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12965 {
12966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12967 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012968 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012969 }
12970
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012971 // Don't allow scan if PNO scan is going on.
12972 if (pHddCtx->isPnoEnable)
12973 {
12974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12975 FL("pno scan in progress"));
12976 return -EBUSY;
12977 }
12978
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012979 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012980 //Channel and action frame is pending
12981 //Otherwise Cancel Remain On Channel and allow Scan
12982 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012983 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012984 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012986 return -EBUSY;
12987 }
12988
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12990 {
12991 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012992 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012993 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012994 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012995 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12996 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012997 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012998 "%s: MAX TM Level Scan not allowed", __func__);
12999 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013000 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013001 }
13002 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13003
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013004 /* Check if scan is allowed at this point of time.
13005 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013006 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013007 {
13008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
13009 return -EBUSY;
13010 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013011
Jeff Johnson295189b2012-06-20 16:38:30 -070013012 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13013
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013014 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13015 * Becasue of this, driver is assuming that this is not wildcard scan and so
13016 * is not aging out the scan results.
13017 */
13018 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013019 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013020 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013022
13023 if ((request->ssids) && (0 < request->n_ssids))
13024 {
13025 tCsrSSIDInfo *SsidInfo;
13026 int j;
13027 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13028 /* Allocate num_ssid tCsrSSIDInfo structure */
13029 SsidInfo = scanRequest.SSIDs.SSIDList =
13030 ( tCsrSSIDInfo *)vos_mem_malloc(
13031 request->n_ssids*sizeof(tCsrSSIDInfo));
13032
13033 if(NULL == scanRequest.SSIDs.SSIDList)
13034 {
13035 hddLog(VOS_TRACE_LEVEL_ERROR,
13036 "%s: memory alloc failed SSIDInfo buffer", __func__);
13037 return -ENOMEM;
13038 }
13039
13040 /* copy all the ssid's and their length */
13041 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13042 {
13043 /* get the ssid length */
13044 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13045 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13046 SsidInfo->SSID.length);
13047 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13048 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13049 j, SsidInfo->SSID.ssId);
13050 }
13051 /* set the scan type to active */
13052 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13053 }
13054 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013055 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013056 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13057 TRACE_CODE_HDD_CFG80211_SCAN,
13058 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013059 /* set the scan type to active */
13060 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013062 else
13063 {
13064 /*Set the scan type to default type, in this case it is ACTIVE*/
13065 scanRequest.scanType = pScanInfo->scan_mode;
13066 }
13067 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13068 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013069
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013070 csr_scan_request_assign_bssid(&scanRequest, request);
13071
Jeff Johnson295189b2012-06-20 16:38:30 -070013072 /* set BSSType to default type */
13073 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13074
13075 /*TODO: scan the requested channels only*/
13076
13077 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013078 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013079 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013080 hddLog(VOS_TRACE_LEVEL_WARN,
13081 "No of Scan Channels exceeded limit: %d", request->n_channels);
13082 request->n_channels = MAX_CHANNEL;
13083 }
13084
13085 hddLog(VOS_TRACE_LEVEL_INFO,
13086 "No of Scan Channels: %d", request->n_channels);
13087
13088
13089 if( request->n_channels )
13090 {
13091 char chList [(request->n_channels*5)+1];
13092 int len;
13093 channelList = vos_mem_malloc( request->n_channels );
13094 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013095 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013096 hddLog(VOS_TRACE_LEVEL_ERROR,
13097 "%s: memory alloc failed channelList", __func__);
13098 status = -ENOMEM;
13099 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013100 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013101
13102 for( i = 0, len = 0; i < request->n_channels ; i++ )
13103 {
13104 channelList[i] = request->channels[i]->hw_value;
13105 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13106 }
13107
Nirav Shah20ac06f2013-12-12 18:14:06 +053013108 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013109 "Channel-List: %s ", chList);
13110 }
c_hpothu53512302014-04-15 18:49:53 +053013111
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013112 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13113 scanRequest.ChannelInfo.ChannelList = channelList;
13114
13115 /* set requestType to full scan */
13116 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13117
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013118 /* if there is back to back scan happening in driver with in
13119 * nDeferScanTimeInterval interval driver should defer new scan request
13120 * and should provide last cached scan results instead of new channel list.
13121 * This rule is not applicable if scan is p2p scan.
13122 * This condition will work only in case when last request no of channels
13123 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013124 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013125 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013126 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013127
Sushant Kaushik86592172015-04-27 16:35:03 +053013128 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13129 /* if wps ie is NULL , then only defer scan */
13130 if ( pWpsIe == NULL &&
13131 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013132 {
13133 if ( pScanInfo->last_scan_timestamp !=0 &&
13134 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13135 {
13136 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13137 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13138 vos_mem_compare(pScanInfo->last_scan_channelList,
13139 channelList, pScanInfo->last_scan_numChannels))
13140 {
13141 hddLog(VOS_TRACE_LEVEL_WARN,
13142 " New and old station scan time differ is less then %u",
13143 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13144
13145 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013146 pAdapter);
13147
Agarwal Ashish57e84372014-12-05 18:26:53 +053013148 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013149 "Return old cached scan as all channels and no of channels are same");
13150
Agarwal Ashish57e84372014-12-05 18:26:53 +053013151 if (0 > ret)
13152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013153
Agarwal Ashish57e84372014-12-05 18:26:53 +053013154 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013155
13156 status = eHAL_STATUS_SUCCESS;
13157 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013158 }
13159 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013160 }
13161
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013162 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13163 * search (Flush on both full scan and social scan but not on single
13164 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13165 */
13166
13167 /* Supplicant does single channel scan after 8-way handshake
13168 * and in that case driver shoudnt flush scan results. If
13169 * driver flushes the scan results here and unfortunately if
13170 * the AP doesnt respond to our probe req then association
13171 * fails which is not desired
13172 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013173 if ((request->n_ssids == 1)
13174 && (request->ssids != NULL)
13175 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13176 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013177
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013178 if( is_p2p_scan ||
13179 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013180 {
13181 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13182 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13183 pAdapter->sessionId );
13184 }
13185
13186 if( request->ie_len )
13187 {
13188 /* save this for future association (join requires this) */
13189 /*TODO: Array needs to be converted to dynamic allocation,
13190 * as multiple ie.s can be sent in cfg80211_scan_request structure
13191 * CR 597966
13192 */
13193 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13194 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13195 pScanInfo->scanAddIE.length = request->ie_len;
13196
13197 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13198 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13199 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013200 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013201 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013202 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013203 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13204 memcpy( pwextBuf->roamProfile.addIEScan,
13205 request->ie, request->ie_len);
13206 }
13207 else
13208 {
13209 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13210 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013211 }
13212
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013213 }
13214 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13215 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13216
13217 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13218 request->ie_len);
13219 if (pP2pIe != NULL)
13220 {
13221#ifdef WLAN_FEATURE_P2P_DEBUG
13222 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13223 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13224 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013225 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013226 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13227 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13228 "Go nego completed to Connection is started");
13229 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13230 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013231 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013232 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13233 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013234 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013235 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13236 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13237 "Disconnected state to Connection is started");
13238 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13239 "for 4way Handshake");
13240 }
13241#endif
13242
13243 /* no_cck will be set during p2p find to disable 11b rates */
13244 if(TRUE == request->no_cck)
13245 {
13246 hddLog(VOS_TRACE_LEVEL_INFO,
13247 "%s: This is a P2P Search", __func__);
13248 scanRequest.p2pSearch = 1;
13249
13250 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013251 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013252 /* set requestType to P2P Discovery */
13253 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13254 }
13255
13256 /*
13257 Skip Dfs Channel in case of P2P Search
13258 if it is set in ini file
13259 */
13260 if(cfg_param->skipDfsChnlInP2pSearch)
13261 {
13262 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013263 }
13264 else
13265 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013266 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013267 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013268
Agarwal Ashish4f616132013-12-30 23:32:50 +053013269 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 }
13271 }
13272
13273 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13274
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013275#ifdef FEATURE_WLAN_TDLS
13276 /* if tdls disagree scan right now, return immediately.
13277 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13278 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13279 */
13280 status = wlan_hdd_tdls_scan_callback (pAdapter,
13281 wiphy,
13282#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13283 dev,
13284#endif
13285 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013286 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013287 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013288 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013289 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13290 "scan rejected %d", __func__, status);
13291 else
13292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13293 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013294 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013295 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013296 }
13297#endif
13298
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013299 /* acquire the wakelock to avoid the apps suspend during the scan. To
13300 * address the following issues.
13301 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13302 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13303 * for long time, this result in apps running at full power for long time.
13304 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13305 * be stuck in full power because of resume BMPS
13306 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013307 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013308
Nirav Shah20ac06f2013-12-12 18:14:06 +053013309 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13310 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013311 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13312 scanRequest.requestType, scanRequest.scanType,
13313 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013314 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13315
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013316 if (pHddCtx->spoofMacAddr.isEnabled &&
13317 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013318 {
13319 hddLog(VOS_TRACE_LEVEL_INFO,
13320 "%s: MAC Spoofing enabled for current scan", __func__);
13321 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13322 * to fill TxBds for probe request during current scan
13323 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013324 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013325 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013326
13327 if(status != VOS_STATUS_SUCCESS)
13328 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013329 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013330 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013331#ifdef FEATURE_WLAN_TDLS
13332 wlan_hdd_tdls_scan_done_callback(pAdapter);
13333#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013334 goto free_mem;
13335 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013336 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013337 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013338 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013339 pAdapter->sessionId, &scanRequest, &scanId,
13340 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013341
Jeff Johnson295189b2012-06-20 16:38:30 -070013342 if (eHAL_STATUS_SUCCESS != status)
13343 {
13344 hddLog(VOS_TRACE_LEVEL_ERROR,
13345 "%s: sme_ScanRequest returned error %d", __func__, status);
13346 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013347 if(eHAL_STATUS_RESOURCES == status)
13348 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13350 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013351 status = -EBUSY;
13352 } else {
13353 status = -EIO;
13354 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013355 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013356
13357#ifdef FEATURE_WLAN_TDLS
13358 wlan_hdd_tdls_scan_done_callback(pAdapter);
13359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013360 goto free_mem;
13361 }
13362
13363 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013364 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013365 pAdapter->request = request;
13366 pScanInfo->scanId = scanId;
13367
13368 complete(&pScanInfo->scan_req_completion_event);
13369
13370free_mem:
13371 if( scanRequest.SSIDs.SSIDList )
13372 {
13373 vos_mem_free(scanRequest.SSIDs.SSIDList);
13374 }
13375
13376 if( channelList )
13377 vos_mem_free( channelList );
13378
13379 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 return status;
13381}
13382
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013383int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13384#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13385 struct net_device *dev,
13386#endif
13387 struct cfg80211_scan_request *request)
13388{
13389 int ret;
13390
13391 vos_ssr_protect(__func__);
13392 ret = __wlan_hdd_cfg80211_scan(wiphy,
13393#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13394 dev,
13395#endif
13396 request);
13397 vos_ssr_unprotect(__func__);
13398
13399 return ret;
13400}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013401
13402void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13403{
13404 v_U8_t iniDot11Mode =
13405 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13406 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13407
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013408 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13409 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013410 switch ( iniDot11Mode )
13411 {
13412 case eHDD_DOT11_MODE_AUTO:
13413 case eHDD_DOT11_MODE_11ac:
13414 case eHDD_DOT11_MODE_11ac_ONLY:
13415#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013416 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13417 sme_IsFeatureSupportedByFW(DOT11AC) )
13418 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13419 else
13420 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013421#else
13422 hddDot11Mode = eHDD_DOT11_MODE_11n;
13423#endif
13424 break;
13425 case eHDD_DOT11_MODE_11n:
13426 case eHDD_DOT11_MODE_11n_ONLY:
13427 hddDot11Mode = eHDD_DOT11_MODE_11n;
13428 break;
13429 default:
13430 hddDot11Mode = iniDot11Mode;
13431 break;
13432 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013433#ifdef WLAN_FEATURE_AP_HT40_24G
13434 if (operationChannel > SIR_11B_CHANNEL_END)
13435#endif
13436 {
13437 /* This call decides required channel bonding mode */
13438 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013439 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13440 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013441 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013442}
13443
Jeff Johnson295189b2012-06-20 16:38:30 -070013444/*
13445 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013446 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013447 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013448int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013449 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13450 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013451{
13452 int status = 0;
13453 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013454 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 v_U32_t roamId;
13456 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013457 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013458 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013459
13460 ENTER();
13461
13462 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013463 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13464
13465 status = wlan_hdd_validate_context(pHddCtx);
13466 if (status)
13467 {
Yue Mae36e3552014-03-05 17:06:20 -080013468 return status;
13469 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013470
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13472 {
13473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13474 return -EINVAL;
13475 }
13476
13477 pRoamProfile = &pWextState->roamProfile;
13478
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013479 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013481 hdd_station_ctx_t *pHddStaCtx;
13482 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013483
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013484 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13485
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013486 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13488 {
13489 /*QoS not enabled in cfg file*/
13490 pRoamProfile->uapsd_mask = 0;
13491 }
13492 else
13493 {
13494 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013495 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13497 }
13498
13499 pRoamProfile->SSIDs.numOfSSIDs = 1;
13500 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13501 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013502 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013503 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13504 ssid, ssid_len);
13505
13506 if (bssid)
13507 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013508 pValidBssid = bssid;
13509 }
13510 else if (bssid_hint)
13511 {
13512 pValidBssid = bssid_hint;
13513 }
13514 if (pValidBssid)
13515 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013516 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013517 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013519 /* Save BSSID in seperate variable as well, as RoamProfile
13520 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013521 case of join failure we should send valid BSSID to supplicant
13522 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013523 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013524 WNI_CFG_BSSID_LEN);
13525 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013526 else
13527 {
13528 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13529 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013530
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013531 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13532 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013533 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13534 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013535 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013536 /*set gen ie*/
13537 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13538 /*set auth*/
13539 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13540 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013541#ifdef FEATURE_WLAN_WAPI
13542 if (pAdapter->wapi_info.nWapiMode)
13543 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013544 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013545 switch (pAdapter->wapi_info.wapiAuthMode)
13546 {
13547 case WAPI_AUTH_MODE_PSK:
13548 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013549 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013550 pAdapter->wapi_info.wapiAuthMode);
13551 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13552 break;
13553 }
13554 case WAPI_AUTH_MODE_CERT:
13555 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013556 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 pAdapter->wapi_info.wapiAuthMode);
13558 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13559 break;
13560 }
13561 } // End of switch
13562 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13563 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13564 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013565 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 pRoamProfile->AuthType.numEntries = 1;
13567 pRoamProfile->EncryptionType.numEntries = 1;
13568 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13569 pRoamProfile->mcEncryptionType.numEntries = 1;
13570 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13571 }
13572 }
13573#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013574#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013575 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013576 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13577 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13578 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013579 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13580 sizeof (tSirGtkOffloadParams));
13581 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013582 }
13583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 pRoamProfile->csrPersona = pAdapter->device_mode;
13585
Jeff Johnson32d95a32012-09-10 13:15:23 -070013586 if( operatingChannel )
13587 {
13588 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13589 pRoamProfile->ChannelInfo.numOfChannels = 1;
13590 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013591 else
13592 {
13593 pRoamProfile->ChannelInfo.ChannelList = NULL;
13594 pRoamProfile->ChannelInfo.numOfChannels = 0;
13595 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013596 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13597 {
13598 hdd_select_cbmode(pAdapter,operatingChannel);
13599 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013600
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013601 /*
13602 * Change conn_state to connecting before sme_RoamConnect(),
13603 * because sme_RoamConnect() has a direct path to call
13604 * hdd_smeRoamCallback(), which will change the conn_state
13605 * If direct path, conn_state will be accordingly changed
13606 * to NotConnected or Associated by either
13607 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13608 * in sme_RoamCallback()
13609 * if sme_RomConnect is to be queued,
13610 * Connecting state will remain until it is completed.
13611 * If connection state is not changed,
13612 * connection state will remain in eConnectionState_NotConnected state.
13613 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13614 * if conn state is eConnectionState_NotConnected.
13615 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13616 * informed of connect result indication which is an issue.
13617 */
13618
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013619 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13620 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013621 {
13622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013623 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013624 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13625 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013626 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013627 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013628 pAdapter->sessionId, pRoamProfile, &roamId);
13629
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013630 if ((eHAL_STATUS_SUCCESS != status) &&
13631 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13632 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013633
13634 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013635 hddLog(VOS_TRACE_LEVEL_ERROR,
13636 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13637 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013638 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013639 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013640 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013641 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013642
13643 pRoamProfile->ChannelInfo.ChannelList = NULL;
13644 pRoamProfile->ChannelInfo.numOfChannels = 0;
13645
Jeff Johnson295189b2012-06-20 16:38:30 -070013646 }
13647 else
13648 {
13649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13650 return -EINVAL;
13651 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013652 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013653 return status;
13654}
13655
13656/*
13657 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13658 * This function is used to set the authentication type (OPEN/SHARED).
13659 *
13660 */
13661static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13662 enum nl80211_auth_type auth_type)
13663{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013664 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013665 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13666
13667 ENTER();
13668
13669 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013670 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013671 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013672 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013673 hddLog(VOS_TRACE_LEVEL_INFO,
13674 "%s: set authentication type to AUTOSWITCH", __func__);
13675 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13676 break;
13677
13678 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013679#ifdef WLAN_FEATURE_VOWIFI_11R
13680 case NL80211_AUTHTYPE_FT:
13681#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013682 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013683 "%s: set authentication type to OPEN", __func__);
13684 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13685 break;
13686
13687 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013688 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013689 "%s: set authentication type to SHARED", __func__);
13690 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13691 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013692#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013693 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013694 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 "%s: set authentication type to CCKM WPA", __func__);
13696 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13697 break;
13698#endif
13699
13700
13701 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013702 hddLog(VOS_TRACE_LEVEL_ERROR,
13703 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013704 auth_type);
13705 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13706 return -EINVAL;
13707 }
13708
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013709 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013710 pHddStaCtx->conn_info.authType;
13711 return 0;
13712}
13713
13714/*
13715 * FUNCTION: wlan_hdd_set_akm_suite
13716 * This function is used to set the key mgmt type(PSK/8021x).
13717 *
13718 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013719static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 u32 key_mgmt
13721 )
13722{
13723 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13724 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013725 /* Should be in ieee802_11_defs.h */
13726#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13727#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013728 /*set key mgmt type*/
13729 switch(key_mgmt)
13730 {
13731 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013732 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013733#ifdef WLAN_FEATURE_VOWIFI_11R
13734 case WLAN_AKM_SUITE_FT_PSK:
13735#endif
13736 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013737 __func__);
13738 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13739 break;
13740
13741 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013742 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013743#ifdef WLAN_FEATURE_VOWIFI_11R
13744 case WLAN_AKM_SUITE_FT_8021X:
13745#endif
13746 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013747 __func__);
13748 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13749 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013750#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013751#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13752#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13753 case WLAN_AKM_SUITE_CCKM:
13754 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13755 __func__);
13756 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13757 break;
13758#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013759#ifndef WLAN_AKM_SUITE_OSEN
13760#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13761 case WLAN_AKM_SUITE_OSEN:
13762 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13763 __func__);
13764 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13765 break;
13766#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013767
13768 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013770 __func__, key_mgmt);
13771 return -EINVAL;
13772
13773 }
13774 return 0;
13775}
13776
13777/*
13778 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013779 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 * (NONE/WEP40/WEP104/TKIP/CCMP).
13781 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013782static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13783 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 bool ucast
13785 )
13786{
13787 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013788 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013789 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13790
13791 ENTER();
13792
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013793 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013795 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013796 __func__, cipher);
13797 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13798 }
13799 else
13800 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013801
Jeff Johnson295189b2012-06-20 16:38:30 -070013802 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013803 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 {
13805 case IW_AUTH_CIPHER_NONE:
13806 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13807 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013808
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013810 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013812
Jeff Johnson295189b2012-06-20 16:38:30 -070013813 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013814 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013816
Jeff Johnson295189b2012-06-20 16:38:30 -070013817 case WLAN_CIPHER_SUITE_TKIP:
13818 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13819 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013820
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 case WLAN_CIPHER_SUITE_CCMP:
13822 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13823 break;
13824#ifdef FEATURE_WLAN_WAPI
13825 case WLAN_CIPHER_SUITE_SMS4:
13826 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13827 break;
13828#endif
13829
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013830#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013831 case WLAN_CIPHER_SUITE_KRK:
13832 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13833 break;
13834#endif
13835 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 __func__, cipher);
13838 return -EOPNOTSUPP;
13839 }
13840 }
13841
13842 if (ucast)
13843 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013844 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013845 __func__, encryptionType);
13846 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13847 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013848 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013849 encryptionType;
13850 }
13851 else
13852 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013853 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013854 __func__, encryptionType);
13855 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13856 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13857 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13858 }
13859
13860 return 0;
13861}
13862
13863
13864/*
13865 * FUNCTION: wlan_hdd_cfg80211_set_ie
13866 * This function is used to parse WPA/RSN IE's.
13867 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013868int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13870 const u8 *ie,
13871#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013872 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013873#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 size_t ie_len
13875 )
13876{
13877 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13879 const u8 *genie = ie;
13880#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013881 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013882#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 v_U16_t remLen = ie_len;
13884#ifdef FEATURE_WLAN_WAPI
13885 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13886 u16 *tmp;
13887 v_U16_t akmsuiteCount;
13888 int *akmlist;
13889#endif
13890 ENTER();
13891
13892 /* clear previous assocAddIE */
13893 pWextState->assocAddIE.length = 0;
13894 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013895 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013896
13897 while (remLen >= 2)
13898 {
13899 v_U16_t eLen = 0;
13900 v_U8_t elementId;
13901 elementId = *genie++;
13902 eLen = *genie++;
13903 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013904
Arif Hussain6d2a3322013-11-17 19:50:10 -080013905 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013907
13908 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013910 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013911 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 -070013912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013913 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 "%s: Invalid WPA IE", __func__);
13915 return -EINVAL;
13916 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013917 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013918 {
13919 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013920 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013922
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013923 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013924 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013925 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13926 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013927 VOS_ASSERT(0);
13928 return -ENOMEM;
13929 }
13930 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13931 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13932 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013933
Jeff Johnson295189b2012-06-20 16:38:30 -070013934 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13935 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13936 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13937 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013938 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13939 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13941 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13942 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13943 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13944 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13945 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013946 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013947 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 {
13949 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013950 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013952
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013953 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013955 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13956 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 VOS_ASSERT(0);
13958 return -ENOMEM;
13959 }
13960 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13961 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13962 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013963
Jeff Johnson295189b2012-06-20 16:38:30 -070013964 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13965 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13966 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013967#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013968 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13969 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 /*Consider WFD IE, only for P2P Client */
13971 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13972 {
13973 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013974 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013975 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013976
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013977 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013978 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013979 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13980 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 VOS_ASSERT(0);
13982 return -ENOMEM;
13983 }
13984 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13985 // WPS IE + P2P IE + WFD IE
13986 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13987 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013988
Jeff Johnson295189b2012-06-20 16:38:30 -070013989 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13990 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13991 }
13992#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013993 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013994 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013995 HS20_OUI_TYPE_SIZE)) )
13996 {
13997 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013998 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013999 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014000
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014001 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014002 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014003 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14004 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014005 VOS_ASSERT(0);
14006 return -ENOMEM;
14007 }
14008 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14009 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014010
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014011 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14012 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14013 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014014 /* Appending OSEN Information Element in Assiciation Request */
14015 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14016 OSEN_OUI_TYPE_SIZE)) )
14017 {
14018 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14019 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14020 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014021
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014022 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014023 {
14024 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14025 "Need bigger buffer space");
14026 VOS_ASSERT(0);
14027 return -ENOMEM;
14028 }
14029 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14030 pWextState->assocAddIE.length += eLen + 2;
14031
14032 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14033 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14034 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14035 }
14036
Abhishek Singh4322e622015-06-10 15:42:54 +053014037 /* Update only for WPA IE */
14038 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14039 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014040
14041 /* populating as ADDIE in beacon frames */
14042 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014043 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014044 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14045 {
14046 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14047 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14048 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14049 {
14050 hddLog(LOGE,
14051 "Coldn't pass "
14052 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14053 }
14054 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14055 else
14056 hddLog(LOGE,
14057 "Could not pass on "
14058 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14059
14060 /* IBSS mode doesn't contain params->proberesp_ies still
14061 beaconIE's need to be populated in probe response frames */
14062 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14063 {
14064 u16 rem_probe_resp_ie_len = eLen + 2;
14065 u8 probe_rsp_ie_len[3] = {0};
14066 u8 counter = 0;
14067
14068 /* Check Probe Resp Length if it is greater then 255 then
14069 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14070 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14071 not able Store More then 255 bytes into One Variable */
14072
14073 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14074 {
14075 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14076 {
14077 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14078 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14079 }
14080 else
14081 {
14082 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14083 rem_probe_resp_ie_len = 0;
14084 }
14085 }
14086
14087 rem_probe_resp_ie_len = 0;
14088
14089 if (probe_rsp_ie_len[0] > 0)
14090 {
14091 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14092 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14093 (tANI_U8*)(genie - 2),
14094 probe_rsp_ie_len[0], NULL,
14095 eANI_BOOLEAN_FALSE)
14096 == eHAL_STATUS_FAILURE)
14097 {
14098 hddLog(LOGE,
14099 "Could not pass"
14100 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14101 }
14102 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14103 }
14104
14105 if (probe_rsp_ie_len[1] > 0)
14106 {
14107 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14108 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14109 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14110 probe_rsp_ie_len[1], NULL,
14111 eANI_BOOLEAN_FALSE)
14112 == eHAL_STATUS_FAILURE)
14113 {
14114 hddLog(LOGE,
14115 "Could not pass"
14116 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14117 }
14118 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14119 }
14120
14121 if (probe_rsp_ie_len[2] > 0)
14122 {
14123 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14124 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14125 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14126 probe_rsp_ie_len[2], NULL,
14127 eANI_BOOLEAN_FALSE)
14128 == eHAL_STATUS_FAILURE)
14129 {
14130 hddLog(LOGE,
14131 "Could not pass"
14132 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14133 }
14134 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14135 }
14136
14137 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14138 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14139 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14140 {
14141 hddLog(LOGE,
14142 "Could not pass"
14143 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14144 }
14145 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014146 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014147 break;
14148 case DOT11F_EID_RSN:
14149 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14150 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14151 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14152 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14153 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14154 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014155
Abhishek Singhb16f3562016-01-20 11:08:32 +053014156 /* Appending extended capabilities with Interworking or
14157 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014158 *
14159 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014160 * interworkingService or bsstransition bit is set to 1.
14161 * Driver is only interested in interworkingService and
14162 * bsstransition capability from supplicant.
14163 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014164 * required from supplicat, it needs to be handled while
14165 * sending Assoc Req in LIM.
14166 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014167 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014168 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014169 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014170 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014171 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014172
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014173 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014174 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014175 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14176 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014177 VOS_ASSERT(0);
14178 return -ENOMEM;
14179 }
14180 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14181 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014182
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014183 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14184 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14185 break;
14186 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014187#ifdef FEATURE_WLAN_WAPI
14188 case WLAN_EID_WAPI:
14189 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014190 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014191 pAdapter->wapi_info.nWapiMode);
14192 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014193 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014194 akmsuiteCount = WPA_GET_LE16(tmp);
14195 tmp = tmp + 1;
14196 akmlist = (int *)(tmp);
14197 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14198 {
14199 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14200 }
14201 else
14202 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014203 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014204 VOS_ASSERT(0);
14205 return -EINVAL;
14206 }
14207
14208 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14209 {
14210 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014211 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014212 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014213 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014214 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014215 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014217 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014218 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14219 }
14220 break;
14221#endif
14222 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014223 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014224 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014225 /* when Unknown IE is received we should break and continue
14226 * to the next IE in the buffer instead we were returning
14227 * so changing this to break */
14228 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014229 }
14230 genie += eLen;
14231 remLen -= eLen;
14232 }
14233 EXIT();
14234 return 0;
14235}
14236
14237/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014238 * FUNCTION: hdd_isWPAIEPresent
14239 * Parse the received IE to find the WPA IE
14240 *
14241 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014242static bool hdd_isWPAIEPresent(
14243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14244 const u8 *ie,
14245#else
14246 u8 *ie,
14247#endif
14248 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014249{
14250 v_U8_t eLen = 0;
14251 v_U16_t remLen = ie_len;
14252 v_U8_t elementId = 0;
14253
14254 while (remLen >= 2)
14255 {
14256 elementId = *ie++;
14257 eLen = *ie++;
14258 remLen -= 2;
14259 if (eLen > remLen)
14260 {
14261 hddLog(VOS_TRACE_LEVEL_ERROR,
14262 "%s: IE length is wrong %d", __func__, eLen);
14263 return FALSE;
14264 }
14265 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14266 {
14267 /* OUI - 0x00 0X50 0XF2
14268 WPA Information Element - 0x01
14269 WPA version - 0x01*/
14270 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14271 return TRUE;
14272 }
14273 ie += eLen;
14274 remLen -= eLen;
14275 }
14276 return FALSE;
14277}
14278
14279/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014280 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014281 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014282 * parameters during connect operation.
14283 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014284int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014285 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014286 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014287{
14288 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014289 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014290 ENTER();
14291
14292 /*set wpa version*/
14293 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14294
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014295 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014296 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014297 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014298 {
14299 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14300 }
14301 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14302 {
14303 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14304 }
14305 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014306
14307 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014308 pWextState->wpaVersion);
14309
14310 /*set authentication type*/
14311 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14312
14313 if (0 > status)
14314 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014315 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 "%s: failed to set authentication type ", __func__);
14317 return status;
14318 }
14319
14320 /*set key mgmt type*/
14321 if (req->crypto.n_akm_suites)
14322 {
14323 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14324 if (0 > status)
14325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014326 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014327 __func__);
14328 return status;
14329 }
14330 }
14331
14332 /*set pairwise cipher type*/
14333 if (req->crypto.n_ciphers_pairwise)
14334 {
14335 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14336 req->crypto.ciphers_pairwise[0], true);
14337 if (0 > status)
14338 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014339 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014340 "%s: failed to set unicast cipher type", __func__);
14341 return status;
14342 }
14343 }
14344 else
14345 {
14346 /*Reset previous cipher suite to none*/
14347 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14348 if (0 > status)
14349 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014350 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014351 "%s: failed to set unicast cipher type", __func__);
14352 return status;
14353 }
14354 }
14355
14356 /*set group cipher type*/
14357 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14358 false);
14359
14360 if (0 > status)
14361 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014362 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014363 __func__);
14364 return status;
14365 }
14366
Chet Lanctot186b5732013-03-18 10:26:30 -070014367#ifdef WLAN_FEATURE_11W
14368 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14369#endif
14370
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14372 if (req->ie_len)
14373 {
14374 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14375 if ( 0 > status)
14376 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014378 __func__);
14379 return status;
14380 }
14381 }
14382
14383 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014384 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014385 {
14386 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14387 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14388 )
14389 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014390 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 __func__);
14395 return -EOPNOTSUPP;
14396 }
14397 else
14398 {
14399 u8 key_len = req->key_len;
14400 u8 key_idx = req->key_idx;
14401
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014402 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 && (CSR_MAX_NUM_KEY > key_idx)
14404 )
14405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014406 hddLog(VOS_TRACE_LEVEL_INFO,
14407 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014408 __func__, key_idx, key_len);
14409 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014410 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014411 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014412 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014413 (u8)key_len;
14414 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14415 }
14416 }
14417 }
14418 }
14419
14420 return status;
14421}
14422
14423/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014424 * FUNCTION: wlan_hdd_try_disconnect
14425 * This function is used to disconnect from previous
14426 * connection
14427 */
14428static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14429{
14430 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014431 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014432 hdd_station_ctx_t *pHddStaCtx;
14433 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014434 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014435
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014436 ret = wlan_hdd_validate_context(pHddCtx);
14437 if (0 != ret)
14438 {
14439 return ret;
14440 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014441 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14442
14443 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14444
14445 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14446 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014447 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014448 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14449 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014450 spin_lock_bh(&pAdapter->lock_for_active_session);
14451 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14452 {
14453 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14454 }
14455 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014456 hdd_connSetConnectionState(pHddStaCtx,
14457 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014458 /* Issue disconnect to CSR */
14459 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014460 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014461 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014462 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14463 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14464 hddLog(LOG1,
14465 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14466 } else if ( 0 != status ) {
14467 hddLog(LOGE,
14468 FL("csrRoamDisconnect failure, returned %d"),
14469 (int)status );
14470 result = -EINVAL;
14471 goto disconnected;
14472 }
14473 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014474 &pAdapter->disconnect_comp_var,
14475 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014476 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14477 hddLog(LOGE,
14478 "%s: Failed to disconnect, timed out", __func__);
14479 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014480 }
14481 }
14482 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14483 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014484 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014485 &pAdapter->disconnect_comp_var,
14486 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014487 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014488 {
14489 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014490 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014491 }
14492 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014493disconnected:
14494 hddLog(LOG1,
14495 FL("Set HDD connState to eConnectionState_NotConnected"));
14496 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14497 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014498}
14499
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014500/**
14501 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14502 * @adapter: Pointer to the HDD adapter
14503 * @req: Pointer to the structure cfg_connect_params receieved from user space
14504 *
14505 * This function will start reassociation if bssid hint, channel hint and
14506 * previous bssid parameters are present in the connect request
14507 *
14508 * Return: success if reassociation is happening
14509 * Error code if reassociation is not permitted or not happening
14510 */
14511#ifdef CFG80211_CONNECT_PREV_BSSID
14512static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14513 struct cfg80211_connect_params *req)
14514{
14515 int status = -EPERM;
14516 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14517 hddLog(VOS_TRACE_LEVEL_INFO,
14518 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14519 req->channel_hint->hw_value,
14520 MAC_ADDR_ARRAY(req->bssid_hint));
14521 status = hdd_reassoc(adapter, req->bssid_hint,
14522 req->channel_hint->hw_value,
14523 CONNECT_CMD_USERSPACE);
14524 }
14525 return status;
14526}
14527#else
14528static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14529 struct cfg80211_connect_params *req)
14530{
14531 return -EPERM;
14532}
14533#endif
14534
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014535/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014536 * FUNCTION: __wlan_hdd_cfg80211_connect
14537 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014538 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014539static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014540 struct net_device *ndev,
14541 struct cfg80211_connect_params *req
14542 )
14543{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014544 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014545 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014546#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14547 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014548 const u8 *bssid_hint = req->bssid_hint;
14549#else
14550 const u8 *bssid_hint = NULL;
14551#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014552 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014553 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014554 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014555
14556 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014557
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014558 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14559 TRACE_CODE_HDD_CFG80211_CONNECT,
14560 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014561 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014562 "%s: device_mode = %s (%d)", __func__,
14563 hdd_device_modetoString(pAdapter->device_mode),
14564 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014565
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014566 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014567 if (!pHddCtx)
14568 {
14569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14570 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014571 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014572 }
14573
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014574 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014575 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014576 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014577 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014578 }
14579
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014580 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14581 if (0 == status)
14582 return status;
14583
Agarwal Ashish51325b52014-06-16 16:50:49 +053014584
Jeff Johnson295189b2012-06-20 16:38:30 -070014585#ifdef WLAN_BTAMP_FEATURE
14586 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014587 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014589 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014590 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014591 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014592 }
14593#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014594
14595 //If Device Mode is Station Concurrent Sessions Exit BMps
14596 //P2P Mode will be taken care in Open/close adapter
14597 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014598 (vos_concurrent_open_sessions_running())) {
14599 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14600 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014601 }
14602
14603 /*Try disconnecting if already in connected state*/
14604 status = wlan_hdd_try_disconnect(pAdapter);
14605 if ( 0 > status)
14606 {
14607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14608 " connection"));
14609 return -EALREADY;
14610 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014611 /* Check for max concurrent connections after doing disconnect if any*/
14612 if (vos_max_concurrent_connections_reached()) {
14613 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14614 return -ECONNREFUSED;
14615 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014616
Jeff Johnson295189b2012-06-20 16:38:30 -070014617 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014618 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014619
14620 if ( 0 > status)
14621 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014623 __func__);
14624 return status;
14625 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014626
14627 if (pHddCtx->spoofMacAddr.isEnabled)
14628 {
14629 hddLog(VOS_TRACE_LEVEL_INFO,
14630 "%s: MAC Spoofing enabled ", __func__);
14631 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14632 * to fill TxBds for probe request during SSID scan which may happen
14633 * as part of connect command
14634 */
14635 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14636 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14637 if (status != VOS_STATUS_SUCCESS)
14638 return -ECONNREFUSED;
14639 }
14640
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014641 if (req->channel)
14642 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014643 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014644 channel = 0;
14645 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14646 req->ssid_len, req->bssid,
14647 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014648
Sushant Kaushikd7083982015-03-18 14:33:24 +053014649 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014650 {
14651 //ReEnable BMPS if disabled
14652 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14653 (NULL != pHddCtx))
14654 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014655 if (pHddCtx->hdd_wlan_suspended)
14656 {
14657 hdd_set_pwrparams(pHddCtx);
14658 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014659 //ReEnable Bmps and Imps back
14660 hdd_enable_bmps_imps(pHddCtx);
14661 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014663 return status;
14664 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014665 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014666 EXIT();
14667 return status;
14668}
14669
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014670static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14671 struct net_device *ndev,
14672 struct cfg80211_connect_params *req)
14673{
14674 int ret;
14675 vos_ssr_protect(__func__);
14676 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14677 vos_ssr_unprotect(__func__);
14678
14679 return ret;
14680}
Jeff Johnson295189b2012-06-20 16:38:30 -070014681
14682/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014683 * FUNCTION: wlan_hdd_disconnect
14684 * This function is used to issue a disconnect request to SME
14685 */
14686int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14687{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014688 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014689 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014690 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014691 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014693 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014694
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014695 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014696 if (0 != status)
14697 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014698 return status;
14699 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014700 /* Indicate sme of disconnect so that in progress connection or preauth
14701 * can be aborted
14702 */
14703 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014704 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014705 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014706
Agarwal Ashish47d18112014-08-04 19:55:07 +053014707 /* Need to apply spin lock before decreasing active sessions
14708 * as there can be chance for double decrement if context switch
14709 * Calls hdd_DisConnectHandler.
14710 */
14711
14712 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014713 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14714 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014715 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14716 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014717 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14718 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014719
Abhishek Singhf4669da2014-05-26 15:07:49 +053014720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014721 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14722
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014723 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014724
Mihir Shete182a0b22014-08-18 16:08:48 +053014725 /*
14726 * stop tx queues before deleting STA/BSS context from the firmware.
14727 * tx has to be disabled because the firmware can get busy dropping
14728 * the tx frames after BSS/STA has been deleted and will not send
14729 * back a response resulting in WDI timeout
14730 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014731 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014732 netif_tx_disable(pAdapter->dev);
14733 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014734
Mihir Shete182a0b22014-08-18 16:08:48 +053014735 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014736 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14737 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014738 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14739 {
14740 hddLog(LOG1,
14741 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014742 }
14743 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014744 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014745 hddLog(LOGE,
14746 FL("csrRoamDisconnect failure, returned %d"),
14747 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014748 result = -EINVAL;
14749 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014750 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014751 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014752 &pAdapter->disconnect_comp_var,
14753 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014754 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014755 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014756 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014757 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014758 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014759 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014760disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014761 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014762 FL("Set HDD connState to eConnectionState_NotConnected"));
14763 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014764#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
14765 /* Sending disconnect event to userspace for kernel version < 3.11
14766 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14767 */
14768 hddLog(LOG1, FL("Send disconnected event to userspace"));
14769
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053014770 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014771 WLAN_REASON_UNSPECIFIED);
14772#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014773
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014774 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014775 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014776}
14777
14778
14779/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014780 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014781 * This function is used to issue a disconnect request to SME
14782 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014783static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014784 struct net_device *dev,
14785 u16 reason
14786 )
14787{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014789 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014790 tCsrRoamProfile *pRoamProfile;
14791 hdd_station_ctx_t *pHddStaCtx;
14792 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014793#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014794 tANI_U8 staIdx;
14795#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014796
Jeff Johnson295189b2012-06-20 16:38:30 -070014797 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014798
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014799 if (!pAdapter) {
14800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14801 return -EINVAL;
14802 }
14803
14804 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14805 if (!pHddStaCtx) {
14806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14807 return -EINVAL;
14808 }
14809
14810 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14811 status = wlan_hdd_validate_context(pHddCtx);
14812 if (0 != status)
14813 {
14814 return status;
14815 }
14816
14817 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14818
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014819 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14820 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14821 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014822 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14823 __func__, hdd_device_modetoString(pAdapter->device_mode),
14824 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014825
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014826 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14827 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014828
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 if (NULL != pRoamProfile)
14830 {
14831 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014832 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14833 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014834 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014835 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014836 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014837 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014838 switch(reason)
14839 {
14840 case WLAN_REASON_MIC_FAILURE:
14841 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14842 break;
14843
14844 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14845 case WLAN_REASON_DISASSOC_AP_BUSY:
14846 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14847 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14848 break;
14849
14850 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14851 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014852 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014853 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14854 break;
14855
Jeff Johnson295189b2012-06-20 16:38:30 -070014856 default:
14857 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14858 break;
14859 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014860 pScanInfo = &pHddCtx->scan_info;
14861 if (pScanInfo->mScanPending)
14862 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014863 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014864 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014865 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014866 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014867 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014868 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014869#ifdef FEATURE_WLAN_TDLS
14870 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014871 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014872 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014873 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14874 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014875 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014876 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014877 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014879 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014880 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014881 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014882 status = sme_DeleteTdlsPeerSta(
14883 WLAN_HDD_GET_HAL_CTX(pAdapter),
14884 pAdapter->sessionId,
14885 mac);
14886 if (status != eHAL_STATUS_SUCCESS) {
14887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14888 return -EPERM;
14889 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014890 }
14891 }
14892#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014893 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014894 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14895 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014896 {
14897 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014898 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014899 __func__, (int)status );
14900 return -EINVAL;
14901 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014902 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014903 else
14904 {
14905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14906 "called while in %d state", __func__,
14907 pHddStaCtx->conn_info.connState);
14908 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014909 }
14910 else
14911 {
14912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14913 }
14914
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014915 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014916 return status;
14917}
14918
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014919static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14920 struct net_device *dev,
14921 u16 reason
14922 )
14923{
14924 int ret;
14925 vos_ssr_protect(__func__);
14926 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14927 vos_ssr_unprotect(__func__);
14928
14929 return ret;
14930}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014931
Jeff Johnson295189b2012-06-20 16:38:30 -070014932/*
14933 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014934 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014935 * settings in IBSS mode.
14936 */
14937static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014938 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014939 struct cfg80211_ibss_params *params
14940 )
14941{
14942 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014943 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14945 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014946
Jeff Johnson295189b2012-06-20 16:38:30 -070014947 ENTER();
14948
14949 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014950 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014951
14952 if (params->ie_len && ( NULL != params->ie) )
14953 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014954 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14955 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 {
14957 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14958 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14959 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014960 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014961 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014962 tDot11fIEWPA dot11WPAIE;
14963 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014964 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014965
Wilson Yang00256342013-10-10 23:13:38 -070014966 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014967 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14968 params->ie_len, DOT11F_EID_WPA);
14969 if ( NULL != ie )
14970 {
14971 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14972 // Unpack the WPA IE
14973 //Skip past the EID byte and length byte - and four byte WiFi OUI
14974 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14975 &ie[2+4],
14976 ie[1] - 4,
14977 &dot11WPAIE);
14978 /*Extract the multicast cipher, the encType for unicast
14979 cipher for wpa-none is none*/
14980 encryptionType =
14981 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14982 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014983 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014984
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14986
14987 if (0 > status)
14988 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014990 __func__);
14991 return status;
14992 }
14993 }
14994
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014995 pWextState->roamProfile.AuthType.authType[0] =
14996 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014997 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14998
14999 if (params->privacy)
15000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015001 /* Security enabled IBSS, At this time there is no information available
15002 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015003 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015004 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015005 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015006 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015007 *enable privacy bit in beacons */
15008
15009 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15010 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015011 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15012 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015013 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15014 pWextState->roamProfile.EncryptionType.numEntries = 1;
15015 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015016 return status;
15017}
15018
15019/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015020 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015021 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015022 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015023static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015024 struct net_device *dev,
15025 struct cfg80211_ibss_params *params
15026 )
15027{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015028 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015029 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15030 tCsrRoamProfile *pRoamProfile;
15031 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015032 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15033 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015034 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015035
15036 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15039 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15040 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015041 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015042 "%s: device_mode = %s (%d)", __func__,
15043 hdd_device_modetoString(pAdapter->device_mode),
15044 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015045
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015046 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015047 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015048 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015049 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015050 }
15051
15052 if (NULL == pWextState)
15053 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015054 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015055 __func__);
15056 return -EIO;
15057 }
15058
Agarwal Ashish51325b52014-06-16 16:50:49 +053015059 if (vos_max_concurrent_connections_reached()) {
15060 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15061 return -ECONNREFUSED;
15062 }
15063
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015064 /*Try disconnecting if already in connected state*/
15065 status = wlan_hdd_try_disconnect(pAdapter);
15066 if ( 0 > status)
15067 {
15068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15069 " IBSS connection"));
15070 return -EALREADY;
15071 }
15072
Jeff Johnson295189b2012-06-20 16:38:30 -070015073 pRoamProfile = &pWextState->roamProfile;
15074
15075 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15076 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015077 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015078 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015079 return -EINVAL;
15080 }
15081
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015082 /* BSSID is provided by upper layers hence no need to AUTO generate */
15083 if (NULL != params->bssid) {
15084 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15085 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15086 hddLog (VOS_TRACE_LEVEL_ERROR,
15087 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15088 return -EIO;
15089 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015090 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015091 }
krunal sonie9002db2013-11-25 14:24:17 -080015092 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15093 {
15094 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15095 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15096 {
15097 hddLog (VOS_TRACE_LEVEL_ERROR,
15098 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15099 return -EIO;
15100 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015101
15102 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015103 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015104 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015105 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015106
Jeff Johnson295189b2012-06-20 16:38:30 -070015107 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015108 if (NULL !=
15109#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15110 params->chandef.chan)
15111#else
15112 params->channel)
15113#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015114 {
15115 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015116 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15117 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15118 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15119 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015120
15121 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015122 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015123 ieee80211_frequency_to_channel(
15124#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15125 params->chandef.chan->center_freq);
15126#else
15127 params->channel->center_freq);
15128#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015129
15130 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15131 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015132 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15134 __func__);
15135 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015136 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015137
15138 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015139 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015140 if (channelNum == validChan[indx])
15141 {
15142 break;
15143 }
15144 }
15145 if (indx >= numChans)
15146 {
15147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015148 __func__, channelNum);
15149 return -EINVAL;
15150 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015151 /* Set the Operational Channel */
15152 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15153 channelNum);
15154 pRoamProfile->ChannelInfo.numOfChannels = 1;
15155 pHddStaCtx->conn_info.operationChannel = channelNum;
15156 pRoamProfile->ChannelInfo.ChannelList =
15157 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015158 }
15159
15160 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015161 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015162 if (status < 0)
15163 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015165 __func__);
15166 return status;
15167 }
15168
15169 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015170 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015171 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015172 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015173
15174 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015176
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015177 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015178 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015179}
15180
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015181static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15182 struct net_device *dev,
15183 struct cfg80211_ibss_params *params
15184 )
15185{
15186 int ret = 0;
15187
15188 vos_ssr_protect(__func__);
15189 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15190 vos_ssr_unprotect(__func__);
15191
15192 return ret;
15193}
15194
Jeff Johnson295189b2012-06-20 16:38:30 -070015195/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015196 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015197 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015198 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015199static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015200 struct net_device *dev
15201 )
15202{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015204 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15205 tCsrRoamProfile *pRoamProfile;
15206 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015207 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015208#ifdef WLAN_FEATURE_RMC
15209 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15210#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015211
15212 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015213
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015214 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15215 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15216 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015217 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015218 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015219 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015220 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015221 }
15222
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015223 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15224 hdd_device_modetoString(pAdapter->device_mode),
15225 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015226 if (NULL == pWextState)
15227 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015228 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015229 __func__);
15230 return -EIO;
15231 }
15232
15233 pRoamProfile = &pWextState->roamProfile;
15234
15235 /* Issue disconnect only if interface type is set to IBSS */
15236 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15237 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015238 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015239 __func__);
15240 return -EINVAL;
15241 }
15242
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015243#ifdef WLAN_FEATURE_RMC
15244 /* Clearing add IE of beacon */
15245 if (ccmCfgSetStr(pHddCtx->hHal,
15246 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15247 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15248 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15249 {
15250 hddLog (VOS_TRACE_LEVEL_ERROR,
15251 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15252 return -EINVAL;
15253 }
15254 if (ccmCfgSetInt(pHddCtx->hHal,
15255 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15256 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15257 {
15258 hddLog (VOS_TRACE_LEVEL_ERROR,
15259 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15260 __func__);
15261 return -EINVAL;
15262 }
15263
15264 // Reset WNI_CFG_PROBE_RSP Flags
15265 wlan_hdd_reset_prob_rspies(pAdapter);
15266
15267 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15268 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15269 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15270 {
15271 hddLog (VOS_TRACE_LEVEL_ERROR,
15272 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15273 __func__);
15274 return -EINVAL;
15275 }
15276#endif
15277
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 /* Issue Disconnect request */
15279 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15280 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15281 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15282
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015283 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015284 return 0;
15285}
15286
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015287static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15288 struct net_device *dev
15289 )
15290{
15291 int ret = 0;
15292
15293 vos_ssr_protect(__func__);
15294 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15295 vos_ssr_unprotect(__func__);
15296
15297 return ret;
15298}
15299
Jeff Johnson295189b2012-06-20 16:38:30 -070015300/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015301 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015302 * This function is used to set the phy parameters
15303 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15304 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015305static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015306 u32 changed)
15307{
15308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15309 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015310 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015311
15312 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015313
15314 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015315 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15316 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015317
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015318 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015319 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015320 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015321 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015322 }
15323
Jeff Johnson295189b2012-06-20 16:38:30 -070015324 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15325 {
15326 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15327 WNI_CFG_RTS_THRESHOLD_STAMAX :
15328 wiphy->rts_threshold;
15329
15330 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015331 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015333 hddLog(VOS_TRACE_LEVEL_ERROR,
15334 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015335 __func__, rts_threshold);
15336 return -EINVAL;
15337 }
15338
15339 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15340 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015341 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015343 hddLog(VOS_TRACE_LEVEL_ERROR,
15344 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015345 __func__, rts_threshold);
15346 return -EIO;
15347 }
15348
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015349 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015350 rts_threshold);
15351 }
15352
15353 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15354 {
15355 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15356 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15357 wiphy->frag_threshold;
15358
15359 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015360 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015362 hddLog(VOS_TRACE_LEVEL_ERROR,
15363 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015364 frag_threshold);
15365 return -EINVAL;
15366 }
15367
15368 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15369 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015370 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015371 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015372 hddLog(VOS_TRACE_LEVEL_ERROR,
15373 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015374 __func__, frag_threshold);
15375 return -EIO;
15376 }
15377
15378 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15379 frag_threshold);
15380 }
15381
15382 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15383 || (changed & WIPHY_PARAM_RETRY_LONG))
15384 {
15385 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15386 wiphy->retry_short :
15387 wiphy->retry_long;
15388
15389 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15390 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15391 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015392 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015393 __func__, retry_value);
15394 return -EINVAL;
15395 }
15396
15397 if (changed & WIPHY_PARAM_RETRY_SHORT)
15398 {
15399 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15400 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015401 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015402 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015403 hddLog(VOS_TRACE_LEVEL_ERROR,
15404 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015405 __func__, retry_value);
15406 return -EIO;
15407 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015408 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 __func__, retry_value);
15410 }
15411 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15412 {
15413 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15414 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015415 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015417 hddLog(VOS_TRACE_LEVEL_ERROR,
15418 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015419 __func__, retry_value);
15420 return -EIO;
15421 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015422 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015423 __func__, retry_value);
15424 }
15425 }
15426
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015427 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015428 return 0;
15429}
15430
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015431static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15432 u32 changed)
15433{
15434 int ret;
15435
15436 vos_ssr_protect(__func__);
15437 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15438 vos_ssr_unprotect(__func__);
15439
15440 return ret;
15441}
15442
Jeff Johnson295189b2012-06-20 16:38:30 -070015443/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015444 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015445 * This function is used to set the txpower
15446 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015447static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015448#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15449 struct wireless_dev *wdev,
15450#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015451#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015452 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015453#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015454 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015455#endif
15456 int dbm)
15457{
15458 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015459 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015460 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15461 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015462 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015463
15464 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015465
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015466 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15467 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15468 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015469 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015470 if (0 != status)
15471 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015472 return status;
15473 }
15474
15475 hHal = pHddCtx->hHal;
15476
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015477 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15478 dbm, ccmCfgSetCallback,
15479 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015481 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15483 return -EIO;
15484 }
15485
15486 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15487 dbm);
15488
15489 switch(type)
15490 {
15491 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15492 /* Fall through */
15493 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15494 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15495 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15497 __func__);
15498 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015499 }
15500 break;
15501 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015503 __func__);
15504 return -EOPNOTSUPP;
15505 break;
15506 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015507 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15508 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015509 return -EIO;
15510 }
15511
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015512 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015513 return 0;
15514}
15515
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015516static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15517#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15518 struct wireless_dev *wdev,
15519#endif
15520#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15521 enum tx_power_setting type,
15522#else
15523 enum nl80211_tx_power_setting type,
15524#endif
15525 int dbm)
15526{
15527 int ret;
15528 vos_ssr_protect(__func__);
15529 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15530#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15531 wdev,
15532#endif
15533#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15534 type,
15535#else
15536 type,
15537#endif
15538 dbm);
15539 vos_ssr_unprotect(__func__);
15540
15541 return ret;
15542}
15543
Jeff Johnson295189b2012-06-20 16:38:30 -070015544/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015545 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015546 * This function is used to read the txpower
15547 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015548static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015549#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15550 struct wireless_dev *wdev,
15551#endif
15552 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015553{
15554
15555 hdd_adapter_t *pAdapter;
15556 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015557 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015558
Jeff Johnsone7245742012-09-05 17:12:55 -070015559 ENTER();
15560
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015561 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015562 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015563 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015564 *dbm = 0;
15565 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015566 }
15567
Jeff Johnson295189b2012-06-20 16:38:30 -070015568 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15569 if (NULL == pAdapter)
15570 {
15571 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15572 return -ENOENT;
15573 }
15574
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015575 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15576 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15577 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015578 wlan_hdd_get_classAstats(pAdapter);
15579 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15580
Jeff Johnsone7245742012-09-05 17:12:55 -070015581 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015582 return 0;
15583}
15584
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015585static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15586#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15587 struct wireless_dev *wdev,
15588#endif
15589 int *dbm)
15590{
15591 int ret;
15592
15593 vos_ssr_protect(__func__);
15594 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15595#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15596 wdev,
15597#endif
15598 dbm);
15599 vos_ssr_unprotect(__func__);
15600
15601 return ret;
15602}
15603
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015604static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15606 const u8* mac,
15607#else
15608 u8* mac,
15609#endif
15610 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015611{
15612 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15613 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15614 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015615 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015616
15617 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15618 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015619
15620 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15621 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15622 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15623 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15624 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15625 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15626 tANI_U16 maxRate = 0;
15627 tANI_U16 myRate;
15628 tANI_U16 currentRate = 0;
15629 tANI_U8 maxSpeedMCS = 0;
15630 tANI_U8 maxMCSIdx = 0;
15631 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015632 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015633 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015634 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015635
Leo Chang6f8870f2013-03-26 18:11:36 -070015636#ifdef WLAN_FEATURE_11AC
15637 tANI_U32 vht_mcs_map;
15638 eDataRate11ACMaxMcs vhtMaxMcs;
15639#endif /* WLAN_FEATURE_11AC */
15640
Jeff Johnsone7245742012-09-05 17:12:55 -070015641 ENTER();
15642
Jeff Johnson295189b2012-06-20 16:38:30 -070015643 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15644 (0 == ssidlen))
15645 {
15646 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15647 " Invalid ssidlen, %d", __func__, ssidlen);
15648 /*To keep GUI happy*/
15649 return 0;
15650 }
15651
Mukul Sharma811205f2014-07-09 21:07:30 +053015652 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15653 {
15654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15655 "%s: Roaming in progress, so unable to proceed this request", __func__);
15656 return 0;
15657 }
15658
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015659 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015660 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015661 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015662 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015663 }
15664
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015665 wlan_hdd_get_station_stats(pAdapter);
15666 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015667
Kiet Lam3b17fc82013-09-27 05:24:08 +053015668 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15669 sinfo->filled |= STATION_INFO_SIGNAL;
15670
c_hpothu09f19542014-05-30 21:53:31 +053015671 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015672 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15673 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015674 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015675 {
15676 rate_flags = pAdapter->maxRateFlags;
15677 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015678
Jeff Johnson295189b2012-06-20 16:38:30 -070015679 //convert to the UI units of 100kbps
15680 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15681
15682#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015683 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 -070015684 sinfo->signal,
15685 pCfg->reportMaxLinkSpeed,
15686 myRate,
15687 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015688 (int) pCfg->linkSpeedRssiMid,
15689 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015690 (int) rate_flags,
15691 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015692#endif //LINKSPEED_DEBUG_ENABLED
15693
15694 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15695 {
15696 // we do not want to necessarily report the current speed
15697 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15698 {
15699 // report the max possible speed
15700 rssidx = 0;
15701 }
15702 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15703 {
15704 // report the max possible speed with RSSI scaling
15705 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15706 {
15707 // report the max possible speed
15708 rssidx = 0;
15709 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015710 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015711 {
15712 // report middle speed
15713 rssidx = 1;
15714 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015715 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15716 {
15717 // report middle speed
15718 rssidx = 2;
15719 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015720 else
15721 {
15722 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015723 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015724 }
15725 }
15726 else
15727 {
15728 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15729 hddLog(VOS_TRACE_LEVEL_ERROR,
15730 "%s: Invalid value for reportMaxLinkSpeed: %u",
15731 __func__, pCfg->reportMaxLinkSpeed);
15732 rssidx = 0;
15733 }
15734
15735 maxRate = 0;
15736
15737 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015738 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15739 OperationalRates, &ORLeng))
15740 {
15741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15742 /*To keep GUI happy*/
15743 return 0;
15744 }
15745
Jeff Johnson295189b2012-06-20 16:38:30 -070015746 for (i = 0; i < ORLeng; i++)
15747 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015748 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015749 {
15750 /* Validate Rate Set */
15751 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15752 {
15753 currentRate = supported_data_rate[j].supported_rate[rssidx];
15754 break;
15755 }
15756 }
15757 /* Update MAX rate */
15758 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15759 }
15760
15761 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015762 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15763 ExtendedRates, &ERLeng))
15764 {
15765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15766 /*To keep GUI happy*/
15767 return 0;
15768 }
15769
Jeff Johnson295189b2012-06-20 16:38:30 -070015770 for (i = 0; i < ERLeng; i++)
15771 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015772 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015773 {
15774 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15775 {
15776 currentRate = supported_data_rate[j].supported_rate[rssidx];
15777 break;
15778 }
15779 }
15780 /* Update MAX rate */
15781 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15782 }
c_hpothu79aab322014-07-14 21:11:01 +053015783
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015784 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015785 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015786 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015787 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015788 {
c_hpothu79aab322014-07-14 21:11:01 +053015789 if (rate_flags & eHAL_TX_RATE_VHT80)
15790 mode = 2;
15791 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15792 mode = 1;
15793 else
15794 mode = 0;
15795
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015796 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15797 MCSRates, &MCSLeng))
15798 {
15799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15800 /*To keep GUI happy*/
15801 return 0;
15802 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015803 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015804#ifdef WLAN_FEATURE_11AC
15805 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015806 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015807 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015808 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015809 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015810 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015811 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015812 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015813 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015814 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015815 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015816 maxMCSIdx = 7;
15817 }
15818 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15819 {
15820 maxMCSIdx = 8;
15821 }
15822 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15823 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015824 //VHT20 is supporting 0~8
15825 if (rate_flags & eHAL_TX_RATE_VHT20)
15826 maxMCSIdx = 8;
15827 else
15828 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015829 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015830
c_hpothu79aab322014-07-14 21:11:01 +053015831 if (0 != rssidx)/*check for scaled */
15832 {
15833 //get middle rate MCS index if rssi=1/2
15834 for (i=0; i <= maxMCSIdx; i++)
15835 {
15836 if (sinfo->signal <= rssiMcsTbl[mode][i])
15837 {
15838 maxMCSIdx = i;
15839 break;
15840 }
15841 }
15842 }
15843
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015844 if (rate_flags & eHAL_TX_RATE_VHT80)
15845 {
15846 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15847 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15848 }
15849 else if (rate_flags & eHAL_TX_RATE_VHT40)
15850 {
15851 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15852 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15853 }
15854 else if (rate_flags & eHAL_TX_RATE_VHT20)
15855 {
15856 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15857 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15858 }
15859
Leo Chang6f8870f2013-03-26 18:11:36 -070015860 maxSpeedMCS = 1;
15861 if (currentRate > maxRate)
15862 {
15863 maxRate = currentRate;
15864 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015865
Leo Chang6f8870f2013-03-26 18:11:36 -070015866 }
15867 else
15868#endif /* WLAN_FEATURE_11AC */
15869 {
15870 if (rate_flags & eHAL_TX_RATE_HT40)
15871 {
15872 rateFlag |= 1;
15873 }
15874 if (rate_flags & eHAL_TX_RATE_SGI)
15875 {
15876 rateFlag |= 2;
15877 }
15878
Girish Gowli01abcee2014-07-31 20:18:55 +053015879 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015880 if (rssidx == 1 || rssidx == 2)
15881 {
15882 //get middle rate MCS index if rssi=1/2
15883 for (i=0; i <= 7; i++)
15884 {
15885 if (sinfo->signal <= rssiMcsTbl[mode][i])
15886 {
15887 temp = i+1;
15888 break;
15889 }
15890 }
15891 }
c_hpothu79aab322014-07-14 21:11:01 +053015892
15893 for (i = 0; i < MCSLeng; i++)
15894 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015895 for (j = 0; j < temp; j++)
15896 {
15897 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15898 {
15899 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015900 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015901 break;
15902 }
15903 }
15904 if ((j < temp) && (currentRate > maxRate))
15905 {
15906 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015907 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015908 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015909 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015910 }
15911 }
15912
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015913 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15914 {
15915 maxRate = myRate;
15916 maxSpeedMCS = 1;
15917 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15918 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015919 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015920 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015921 {
15922 maxRate = myRate;
15923 if (rate_flags & eHAL_TX_RATE_LEGACY)
15924 {
15925 maxSpeedMCS = 0;
15926 }
15927 else
15928 {
15929 maxSpeedMCS = 1;
15930 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15931 }
15932 }
15933
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015934 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015935 {
15936 sinfo->txrate.legacy = maxRate;
15937#ifdef LINKSPEED_DEBUG_ENABLED
15938 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15939#endif //LINKSPEED_DEBUG_ENABLED
15940 }
15941 else
15942 {
15943 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015944#ifdef WLAN_FEATURE_11AC
15945 sinfo->txrate.nss = 1;
15946 if (rate_flags & eHAL_TX_RATE_VHT80)
15947 {
15948 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015949 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015950 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015951 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015952 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015953 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15954 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15955 }
15956 else if (rate_flags & eHAL_TX_RATE_VHT20)
15957 {
15958 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15959 }
15960#endif /* WLAN_FEATURE_11AC */
15961 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15962 {
15963 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15964 if (rate_flags & eHAL_TX_RATE_HT40)
15965 {
15966 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15967 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015968 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015969 if (rate_flags & eHAL_TX_RATE_SGI)
15970 {
15971 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15972 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015973
Jeff Johnson295189b2012-06-20 16:38:30 -070015974#ifdef LINKSPEED_DEBUG_ENABLED
15975 pr_info("Reporting MCS rate %d flags %x\n",
15976 sinfo->txrate.mcs,
15977 sinfo->txrate.flags );
15978#endif //LINKSPEED_DEBUG_ENABLED
15979 }
15980 }
15981 else
15982 {
15983 // report current rate instead of max rate
15984
15985 if (rate_flags & eHAL_TX_RATE_LEGACY)
15986 {
15987 //provide to the UI in units of 100kbps
15988 sinfo->txrate.legacy = myRate;
15989#ifdef LINKSPEED_DEBUG_ENABLED
15990 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15991#endif //LINKSPEED_DEBUG_ENABLED
15992 }
15993 else
15994 {
15995 //must be MCS
15996 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015997#ifdef WLAN_FEATURE_11AC
15998 sinfo->txrate.nss = 1;
15999 if (rate_flags & eHAL_TX_RATE_VHT80)
16000 {
16001 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16002 }
16003 else
16004#endif /* WLAN_FEATURE_11AC */
16005 {
16006 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16007 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 if (rate_flags & eHAL_TX_RATE_SGI)
16009 {
16010 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16011 }
16012 if (rate_flags & eHAL_TX_RATE_HT40)
16013 {
16014 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16015 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016016#ifdef WLAN_FEATURE_11AC
16017 else if (rate_flags & eHAL_TX_RATE_VHT80)
16018 {
16019 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16020 }
16021#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016022#ifdef LINKSPEED_DEBUG_ENABLED
16023 pr_info("Reporting actual MCS rate %d flags %x\n",
16024 sinfo->txrate.mcs,
16025 sinfo->txrate.flags );
16026#endif //LINKSPEED_DEBUG_ENABLED
16027 }
16028 }
16029 sinfo->filled |= STATION_INFO_TX_BITRATE;
16030
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016031 sinfo->tx_packets =
16032 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16033 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16034 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16035 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16036
16037 sinfo->tx_retries =
16038 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16039 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16040 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16041 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16042
16043 sinfo->tx_failed =
16044 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16045 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16046 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16047 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16048
16049 sinfo->filled |=
16050 STATION_INFO_TX_PACKETS |
16051 STATION_INFO_TX_RETRIES |
16052 STATION_INFO_TX_FAILED;
16053
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016054 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16055 sinfo->filled |= STATION_INFO_RX_PACKETS;
16056
16057 if (rate_flags & eHAL_TX_RATE_LEGACY)
16058 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16059 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16060 sinfo->rx_packets);
16061 else
16062 hddLog(LOG1,
16063 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16064 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16065 sinfo->tx_packets, sinfo->rx_packets);
16066
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016067 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16068 TRACE_CODE_HDD_CFG80211_GET_STA,
16069 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016070 EXIT();
16071 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016072}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16074static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16075 const u8* mac, struct station_info *sinfo)
16076#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016077static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16078 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016079#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016080{
16081 int ret;
16082
16083 vos_ssr_protect(__func__);
16084 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16085 vos_ssr_unprotect(__func__);
16086
16087 return ret;
16088}
16089
16090static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016091 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016092{
16093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016094 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016095 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016096 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016097
Jeff Johnsone7245742012-09-05 17:12:55 -070016098 ENTER();
16099
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 if (NULL == pAdapter)
16101 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016103 return -ENODEV;
16104 }
16105
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016106 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16107 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16108 pAdapter->sessionId, timeout));
16109
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016110 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016111 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016112 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016113 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016114 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016115 }
16116
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016117 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16118 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16119 (pHddCtx->cfg_ini->fhostArpOffload) &&
16120 (eConnectionState_Associated ==
16121 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16122 {
Amar Singhald53568e2013-09-26 11:03:45 -070016123
16124 hddLog(VOS_TRACE_LEVEL_INFO,
16125 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016126 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016127 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16128 {
16129 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016130 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016131 __func__, vos_status);
16132 }
16133 }
16134
Jeff Johnson295189b2012-06-20 16:38:30 -070016135 /**The get power cmd from the supplicant gets updated by the nl only
16136 *on successful execution of the function call
16137 *we are oppositely mapped w.r.t mode in the driver
16138 **/
16139 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16140
16141 if (VOS_STATUS_E_FAILURE == vos_status)
16142 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16144 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016145 return -EINVAL;
16146 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016147 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016148 return 0;
16149}
16150
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016151static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16152 struct net_device *dev, bool mode, int timeout)
16153{
16154 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016155
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016156 vos_ssr_protect(__func__);
16157 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16158 vos_ssr_unprotect(__func__);
16159
16160 return ret;
16161}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016162
Jeff Johnson295189b2012-06-20 16:38:30 -070016163#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016164static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16165 struct net_device *netdev,
16166 u8 key_index)
16167{
16168 ENTER();
16169 return 0;
16170}
16171
Jeff Johnson295189b2012-06-20 16:38:30 -070016172static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016173 struct net_device *netdev,
16174 u8 key_index)
16175{
16176 int ret;
16177 vos_ssr_protect(__func__);
16178 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16179 vos_ssr_unprotect(__func__);
16180 return ret;
16181}
16182#endif //LINUX_VERSION_CODE
16183
16184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16185static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16186 struct net_device *dev,
16187 struct ieee80211_txq_params *params)
16188{
16189 ENTER();
16190 return 0;
16191}
16192#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16193static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16194 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016195{
Jeff Johnsone7245742012-09-05 17:12:55 -070016196 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016197 return 0;
16198}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016199#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016200
16201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16202static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016203 struct net_device *dev,
16204 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016205{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016206 int ret;
16207
16208 vos_ssr_protect(__func__);
16209 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16210 vos_ssr_unprotect(__func__);
16211 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016212}
16213#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16214static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16215 struct ieee80211_txq_params *params)
16216{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016217 int ret;
16218
16219 vos_ssr_protect(__func__);
16220 ret = __wlan_hdd_set_txq_params(wiphy, params);
16221 vos_ssr_unprotect(__func__);
16222 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016223}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016224#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016225
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016226static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016227 struct net_device *dev,
16228 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016229{
16230 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016231 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016232 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016233 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016234 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016235 v_CONTEXT_t pVosContext = NULL;
16236 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016237
Jeff Johnsone7245742012-09-05 17:12:55 -070016238 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016239
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016240 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016241 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016243 return -EINVAL;
16244 }
16245
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016246 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16247 TRACE_CODE_HDD_CFG80211_DEL_STA,
16248 pAdapter->sessionId, pAdapter->device_mode));
16249
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016250 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16251 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016252 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016253 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016254 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016255 }
16256
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016258 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016259 )
16260 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016261 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16262 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16263 if(pSapCtx == NULL){
16264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16265 FL("psapCtx is NULL"));
16266 return -ENOENT;
16267 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016268 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016269 {
16270 v_U16_t i;
16271 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16272 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016273 if ((pSapCtx->aStaInfo[i].isUsed) &&
16274 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016276 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016277 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016278 ETHER_ADDR_LEN);
16279
Jeff Johnson295189b2012-06-20 16:38:30 -070016280 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016281 "%s: Delete STA with MAC::"
16282 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016283 __func__,
16284 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16285 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016286 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016287 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016288 }
16289 }
16290 }
16291 else
16292 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016293
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016294 vos_status = hdd_softap_GetStaId(pAdapter,
16295 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016296 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16297 {
16298 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016299 "%s: Skip this DEL STA as this is not used::"
16300 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016301 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016302 return -ENOENT;
16303 }
16304
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016305 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016306 {
16307 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016308 "%s: Skip this DEL STA as deauth is in progress::"
16309 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016310 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016311 return -ENOENT;
16312 }
16313
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016314 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016315
Jeff Johnson295189b2012-06-20 16:38:30 -070016316 hddLog(VOS_TRACE_LEVEL_INFO,
16317 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016318 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016319 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016320 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016321
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016322 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016323 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16324 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016325 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016326 hddLog(VOS_TRACE_LEVEL_INFO,
16327 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016328 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016329 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016330 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016331 return -ENOENT;
16332 }
16333
Jeff Johnson295189b2012-06-20 16:38:30 -070016334 }
16335 }
16336
16337 EXIT();
16338
16339 return 0;
16340}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016341
16342#ifdef CFG80211_DEL_STA_V2
16343static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16344 struct net_device *dev,
16345 struct station_del_parameters *param)
16346#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016347#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16348static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16349 struct net_device *dev, const u8 *mac)
16350#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016351static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16352 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016353#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016354#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016355{
16356 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016357 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016358
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016359 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016360
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016361#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016362 if (NULL == param) {
16363 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016364 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016365 return -EINVAL;
16366 }
16367
16368 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16369 param->subtype, &delStaParams);
16370
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016371#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016372 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016373 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016374#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016375 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16376
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016377 vos_ssr_unprotect(__func__);
16378
16379 return ret;
16380}
16381
16382static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016383 struct net_device *dev,
16384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16385 const u8 *mac,
16386#else
16387 u8 *mac,
16388#endif
16389 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016390{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016391 hdd_adapter_t *pAdapter;
16392 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016393 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016394#ifdef FEATURE_WLAN_TDLS
16395 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016396
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016397 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016398
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016399 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16400 if (NULL == pAdapter)
16401 {
16402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16403 "%s: Adapter is NULL",__func__);
16404 return -EINVAL;
16405 }
16406 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16407 status = wlan_hdd_validate_context(pHddCtx);
16408 if (0 != status)
16409 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016410 return status;
16411 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016412
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016413 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16414 TRACE_CODE_HDD_CFG80211_ADD_STA,
16415 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016416 mask = params->sta_flags_mask;
16417
16418 set = params->sta_flags_set;
16419
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016421 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16422 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016423
16424 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16425 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016426 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016427 }
16428 }
16429#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016430 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016431 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016432}
16433
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16435static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16436 struct net_device *dev, const u8 *mac,
16437 struct station_parameters *params)
16438#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016439static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16440 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016441#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016442{
16443 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016444
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016445 vos_ssr_protect(__func__);
16446 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16447 vos_ssr_unprotect(__func__);
16448
16449 return ret;
16450}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016451#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016452
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016453static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016454 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016455{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16457 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016458 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016459 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016460 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016461 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016463 ENTER();
16464
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016465 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016466 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016467 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016469 return -EINVAL;
16470 }
16471
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016472 if (!pmksa) {
16473 hddLog(LOGE, FL("pmksa is NULL"));
16474 return -EINVAL;
16475 }
16476
16477 if (!pmksa->bssid || !pmksa->pmkid) {
16478 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16479 pmksa->bssid, pmksa->pmkid);
16480 return -EINVAL;
16481 }
16482
16483 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16484 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16485
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016486 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16487 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016488 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016489 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016490 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016491 }
16492
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016493 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016494 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16495
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016496 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16497 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016498
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016499 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016500 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016501 &pmk_id, 1, FALSE);
16502
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016503 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16504 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16505 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016507 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016508 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016509}
16510
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016511static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16512 struct cfg80211_pmksa *pmksa)
16513{
16514 int ret;
16515
16516 vos_ssr_protect(__func__);
16517 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16518 vos_ssr_unprotect(__func__);
16519
16520 return ret;
16521}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016522
Wilson Yang6507c4e2013-10-01 20:11:19 -070016523
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016524static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016525 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016526{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16528 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016529 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016530 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016532 ENTER();
16533
Wilson Yang6507c4e2013-10-01 20:11:19 -070016534 /* Validate pAdapter */
16535 if (NULL == pAdapter)
16536 {
16537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16538 return -EINVAL;
16539 }
16540
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016541 if (!pmksa) {
16542 hddLog(LOGE, FL("pmksa is NULL"));
16543 return -EINVAL;
16544 }
16545
16546 if (!pmksa->bssid) {
16547 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16548 return -EINVAL;
16549 }
16550
Kiet Lam98c46a12014-10-31 15:34:57 -070016551 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16552 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16553
Wilson Yang6507c4e2013-10-01 20:11:19 -070016554 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16555 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016556 if (0 != status)
16557 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016558 return status;
16559 }
16560
16561 /*Retrieve halHandle*/
16562 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16563
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016564 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16565 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16566 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016567 /* Delete the PMKID CSR cache */
16568 if (eHAL_STATUS_SUCCESS !=
16569 sme_RoamDelPMKIDfromCache(halHandle,
16570 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16571 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16572 MAC_ADDR_ARRAY(pmksa->bssid));
16573 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016574 }
16575
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016576 EXIT();
16577 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016578}
16579
Wilson Yang6507c4e2013-10-01 20:11:19 -070016580
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016581static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16582 struct cfg80211_pmksa *pmksa)
16583{
16584 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016585
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016586 vos_ssr_protect(__func__);
16587 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16588 vos_ssr_unprotect(__func__);
16589
16590 return ret;
16591
16592}
16593
16594static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016595{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16597 tHalHandle halHandle;
16598 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016599 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016600
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016601 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016602
16603 /* Validate pAdapter */
16604 if (NULL == pAdapter)
16605 {
16606 hddLog(VOS_TRACE_LEVEL_ERROR,
16607 "%s: Invalid Adapter" ,__func__);
16608 return -EINVAL;
16609 }
16610
16611 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16612 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016613 if (0 != status)
16614 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016615 return status;
16616 }
16617
16618 /*Retrieve halHandle*/
16619 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16620
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016621 /* Flush the PMKID cache in CSR */
16622 if (eHAL_STATUS_SUCCESS !=
16623 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16625 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016626 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016627 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016628 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016629}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016630
16631static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16632{
16633 int ret;
16634
16635 vos_ssr_protect(__func__);
16636 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16637 vos_ssr_unprotect(__func__);
16638
16639 return ret;
16640}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016641#endif
16642
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016643#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016644static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16645 struct net_device *dev,
16646 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016647{
16648 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16649 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016650 hdd_context_t *pHddCtx;
16651 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016652
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016653 ENTER();
16654
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016655 if (NULL == pAdapter)
16656 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016658 return -ENODEV;
16659 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16661 ret = wlan_hdd_validate_context(pHddCtx);
16662 if (0 != ret)
16663 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016664 return ret;
16665 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016666 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016667 if (NULL == pHddStaCtx)
16668 {
16669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16670 return -EINVAL;
16671 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016672
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016673 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16674 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16675 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016676 // Added for debug on reception of Re-assoc Req.
16677 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16678 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016679 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016680 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016681 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016682 }
16683
16684#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016685 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016686 ftie->ie_len);
16687#endif
16688
16689 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016690 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16691 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016692 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016693
16694 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016695 return 0;
16696}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016697
16698static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16699 struct net_device *dev,
16700 struct cfg80211_update_ft_ies_params *ftie)
16701{
16702 int ret;
16703
16704 vos_ssr_protect(__func__);
16705 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16706 vos_ssr_unprotect(__func__);
16707
16708 return ret;
16709}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016710#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016711
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016712#ifdef FEATURE_WLAN_SCAN_PNO
16713
16714void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16715 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16716{
16717 int ret;
16718 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16719 hdd_context_t *pHddCtx;
16720
Nirav Shah80830bf2013-12-31 16:35:12 +053016721 ENTER();
16722
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016723 if (NULL == pAdapter)
16724 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016726 "%s: HDD adapter is Null", __func__);
16727 return ;
16728 }
16729
16730 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16731 if (NULL == pHddCtx)
16732 {
16733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16734 "%s: HDD context is Null!!!", __func__);
16735 return ;
16736 }
16737
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016738 spin_lock(&pHddCtx->schedScan_lock);
16739 if (TRUE == pHddCtx->isWiphySuspended)
16740 {
16741 pHddCtx->isSchedScanUpdatePending = TRUE;
16742 spin_unlock(&pHddCtx->schedScan_lock);
16743 hddLog(VOS_TRACE_LEVEL_INFO,
16744 "%s: Update cfg80211 scan database after it resume", __func__);
16745 return ;
16746 }
16747 spin_unlock(&pHddCtx->schedScan_lock);
16748
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016749 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16750
16751 if (0 > ret)
16752 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016753 else
16754 {
16755 /* Acquire wakelock to handle the case where APP's tries to suspend
16756 * immediatly after the driver gets connect request(i.e after pno)
16757 * from supplicant, this result in app's is suspending and not able
16758 * to process the connect request to AP */
16759 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16760 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016761 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16763 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016764}
16765
16766/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016767 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016768 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016769 */
16770static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16771{
16772 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16773 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016774 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016775 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16776 int status = 0;
16777 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16778
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016779 /* The current firmware design does not allow PNO during any
16780 * active sessions. Hence, determine the active sessions
16781 * and return a failure.
16782 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016783 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16784 {
16785 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016786 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016787
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016788 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16789 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16790 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16791 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16792 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016793 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016794 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016795 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016796 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016797 }
16798 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16799 pAdapterNode = pNext;
16800 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016801 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016802}
16803
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016804void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16805{
16806 hdd_adapter_t *pAdapter = callbackContext;
16807 hdd_context_t *pHddCtx;
16808
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016809 ENTER();
16810
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016811 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16812 {
16813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16814 FL("Invalid adapter or adapter has invalid magic"));
16815 return;
16816 }
16817
16818 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16819 if (0 != wlan_hdd_validate_context(pHddCtx))
16820 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016821 return;
16822 }
16823
c_hpothub53c45d2014-08-18 16:53:14 +053016824 if (VOS_STATUS_SUCCESS != status)
16825 {
16826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016827 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016828 pHddCtx->isPnoEnable = FALSE;
16829 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016830
16831 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16832 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016833 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016834}
16835
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016836/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016837 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16838 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016839 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016840static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016841 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16842{
16843 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016844 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016845 hdd_context_t *pHddCtx;
16846 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016847 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016848 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16849 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016850 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16851 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016852 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016853 hdd_config_t *pConfig = NULL;
16854 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016855
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016856 ENTER();
16857
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016858 if (NULL == pAdapter)
16859 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016861 "%s: HDD adapter is Null", __func__);
16862 return -ENODEV;
16863 }
16864
16865 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016866 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016867
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016868 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016869 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016870 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016871 }
16872
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016873 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016874 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16875 if (NULL == hHal)
16876 {
16877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16878 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016879 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016880 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016881 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16882 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16883 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016884 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016885 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016886 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016887 {
16888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16889 "%s: aborting the existing scan is unsuccessfull", __func__);
16890 return -EBUSY;
16891 }
16892
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016893 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016894 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016896 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016897 return -EBUSY;
16898 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016899
c_hpothu37f21312014-04-09 21:49:54 +053016900 if (TRUE == pHddCtx->isPnoEnable)
16901 {
16902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16903 FL("already PNO is enabled"));
16904 return -EBUSY;
16905 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016906
16907 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16908 {
16909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16910 "%s: abort ROC failed ", __func__);
16911 return -EBUSY;
16912 }
16913
c_hpothu37f21312014-04-09 21:49:54 +053016914 pHddCtx->isPnoEnable = TRUE;
16915
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016916 pnoRequest.enable = 1; /*Enable PNO */
16917 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016918
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016919 if (( !pnoRequest.ucNetworksCount ) ||
16920 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016921 {
16922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016923 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016924 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016925 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016926 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016927 goto error;
16928 }
16929
16930 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16931 {
16932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016933 "%s: Incorrect number of channels %d",
16934 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016935 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016936 goto error;
16937 }
16938
16939 /* Framework provides one set of channels(all)
16940 * common for all saved profile */
16941 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16942 channels_allowed, &num_channels_allowed))
16943 {
16944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16945 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016946 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016947 goto error;
16948 }
16949 /* Checking each channel against allowed channel list */
16950 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016951 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016952 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016953 char chList [(request->n_channels*5)+1];
16954 int len;
16955 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016956 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016957 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016958 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016959 if (request->channels[i]->hw_value == channels_allowed[indx])
16960 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016961 if ((!pConfig->enableDFSPnoChnlScan) &&
16962 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16963 {
16964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16965 "%s : Dropping DFS channel : %d",
16966 __func__,channels_allowed[indx]);
16967 num_ignore_dfs_ch++;
16968 break;
16969 }
16970
Nirav Shah80830bf2013-12-31 16:35:12 +053016971 valid_ch[num_ch++] = request->channels[i]->hw_value;
16972 len += snprintf(chList+len, 5, "%d ",
16973 request->channels[i]->hw_value);
16974 break ;
16975 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016976 }
16977 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016978 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016979
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016980 /*If all channels are DFS and dropped, then ignore the PNO request*/
16981 if (num_ignore_dfs_ch == request->n_channels)
16982 {
16983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16984 "%s : All requested channels are DFS channels", __func__);
16985 ret = -EINVAL;
16986 goto error;
16987 }
16988 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016989
16990 pnoRequest.aNetworks =
16991 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16992 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016993 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016994 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16995 FL("failed to allocate memory aNetworks %u"),
16996 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16997 goto error;
16998 }
16999 vos_mem_zero(pnoRequest.aNetworks,
17000 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17001
17002 /* Filling per profile params */
17003 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17004 {
17005 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017006 request->match_sets[i].ssid.ssid_len;
17007
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017008 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17009 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017010 {
17011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017012 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017013 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017014 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017015 goto error;
17016 }
17017
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017018 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017019 request->match_sets[i].ssid.ssid,
17020 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17022 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017023 i, pnoRequest.aNetworks[i].ssId.ssId);
17024 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17025 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17026 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017027
17028 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017029 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17030 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017031
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017032 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017033 }
17034
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017035 for (i = 0; i < request->n_ssids; i++)
17036 {
17037 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017038 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017039 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017040 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017041 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017042 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017043 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017044 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017045 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017046 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017047 break;
17048 }
17049 j++;
17050 }
17051 }
17052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17053 "Number of hidden networks being Configured = %d",
17054 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017056 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017057
17058 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17059 if (pnoRequest.p24GProbeTemplate == NULL)
17060 {
17061 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17062 FL("failed to allocate memory p24GProbeTemplate %u"),
17063 SIR_PNO_MAX_PB_REQ_SIZE);
17064 goto error;
17065 }
17066
17067 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17068 if (pnoRequest.p5GProbeTemplate == NULL)
17069 {
17070 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17071 FL("failed to allocate memory p5GProbeTemplate %u"),
17072 SIR_PNO_MAX_PB_REQ_SIZE);
17073 goto error;
17074 }
17075
17076 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17077 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17078
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017079 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17080 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017081 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017082 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17083 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17084 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017085
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017086 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17087 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17088 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017089 }
17090
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017091 /* Driver gets only one time interval which is hardcoded in
17092 * supplicant for 10000ms. Taking power consumption into account 6 timers
17093 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17094 * 80,160,320 secs. And number of scan cycle for each timer
17095 * is configurable through INI param gPNOScanTimerRepeatValue.
17096 * If it is set to 0 only one timer will be used and PNO scan cycle
17097 * will be repeated after each interval specified by supplicant
17098 * till PNO is disabled.
17099 */
17100 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017101 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017102 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017103 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017104 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17105
17106 tempInterval = (request->interval)/1000;
17107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17108 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17109 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017110 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017111 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017112 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017113 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017114 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017115 tempInterval *= 2;
17116 }
17117 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017118 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017119
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017120 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017121
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017122 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017123 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17124 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017125 pAdapter->pno_req_status = 0;
17126
Nirav Shah80830bf2013-12-31 16:35:12 +053017127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17128 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017129 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17130 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017131
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017132 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017133 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017134 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17135 if (eHAL_STATUS_SUCCESS != status)
17136 {
17137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017138 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017139 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017140 goto error;
17141 }
17142
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017143 ret = wait_for_completion_timeout(
17144 &pAdapter->pno_comp_var,
17145 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17146 if (0 >= ret)
17147 {
17148 // Did not receive the response for PNO enable in time.
17149 // Assuming the PNO enable was success.
17150 // Returning error from here, because we timeout, results
17151 // in side effect of Wifi (Wifi Setting) not to work.
17152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17153 FL("Timed out waiting for PNO to be Enabled"));
17154 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017155 }
17156
17157 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017158 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017159
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017160error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17162 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017163 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017164 if (pnoRequest.aNetworks)
17165 vos_mem_free(pnoRequest.aNetworks);
17166 if (pnoRequest.p24GProbeTemplate)
17167 vos_mem_free(pnoRequest.p24GProbeTemplate);
17168 if (pnoRequest.p5GProbeTemplate)
17169 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017170
17171 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017172 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017173}
17174
17175/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017176 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17177 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017178 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017179static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17180 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17181{
17182 int ret;
17183
17184 vos_ssr_protect(__func__);
17185 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17186 vos_ssr_unprotect(__func__);
17187
17188 return ret;
17189}
17190
17191/*
17192 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17193 * Function to disable PNO
17194 */
17195static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017196 struct net_device *dev)
17197{
17198 eHalStatus status = eHAL_STATUS_FAILURE;
17199 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17200 hdd_context_t *pHddCtx;
17201 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017202 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017203 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017204
17205 ENTER();
17206
17207 if (NULL == pAdapter)
17208 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017210 "%s: HDD adapter is Null", __func__);
17211 return -ENODEV;
17212 }
17213
17214 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017215
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017216 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017217 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017219 "%s: HDD context is Null", __func__);
17220 return -ENODEV;
17221 }
17222
17223 /* The return 0 is intentional when isLogpInProgress and
17224 * isLoadUnloadInProgress. We did observe a crash due to a return of
17225 * failure in sched_scan_stop , especially for a case where the unload
17226 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17227 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17228 * success. If it returns a failure , then its next invocation due to the
17229 * clean up of the second interface will have the dev pointer corresponding
17230 * to the first one leading to a crash.
17231 */
17232 if (pHddCtx->isLogpInProgress)
17233 {
17234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17235 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017236 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017237 return ret;
17238 }
17239
Mihir Shete18156292014-03-11 15:38:30 +053017240 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017241 {
17242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17243 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17244 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017245 }
17246
17247 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17248 if (NULL == hHal)
17249 {
17250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17251 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017252 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017253 }
17254
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017255 pnoRequest.enable = 0; /* Disable PNO */
17256 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017257
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017258 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17259 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17260 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017261
17262 INIT_COMPLETION(pAdapter->pno_comp_var);
17263 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17264 pnoRequest.callbackContext = pAdapter;
17265 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017266 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017267 pAdapter->sessionId,
17268 NULL, pAdapter);
17269 if (eHAL_STATUS_SUCCESS != status)
17270 {
17271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17272 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017273 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017274 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017275 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017276 ret = wait_for_completion_timeout(
17277 &pAdapter->pno_comp_var,
17278 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17279 if (0 >= ret)
17280 {
17281 // Did not receive the response for PNO disable in time.
17282 // Assuming the PNO disable was success.
17283 // Returning error from here, because we timeout, results
17284 // in side effect of Wifi (Wifi Setting) not to work.
17285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17286 FL("Timed out waiting for PNO to be disabled"));
17287 ret = 0;
17288 }
17289
17290 ret = pAdapter->pno_req_status;
17291 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017292
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017293error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017295 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017296
17297 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017298 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017299}
17300
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017301/*
17302 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17303 * NL interface to disable PNO
17304 */
17305static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17306 struct net_device *dev)
17307{
17308 int ret;
17309
17310 vos_ssr_protect(__func__);
17311 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17312 vos_ssr_unprotect(__func__);
17313
17314 return ret;
17315}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017316#endif /*FEATURE_WLAN_SCAN_PNO*/
17317
17318
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017319#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017320#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017321static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17322 struct net_device *dev,
17323 u8 *peer, u8 action_code,
17324 u8 dialog_token,
17325 u16 status_code, u32 peer_capability,
17326 const u8 *buf, size_t len)
17327#else /* TDLS_MGMT_VERSION2 */
17328#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17329static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17330 struct net_device *dev,
17331 const u8 *peer, u8 action_code,
17332 u8 dialog_token, u16 status_code,
17333 u32 peer_capability, bool initiator,
17334 const u8 *buf, size_t len)
17335#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17336static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17337 struct net_device *dev,
17338 const u8 *peer, u8 action_code,
17339 u8 dialog_token, u16 status_code,
17340 u32 peer_capability, const u8 *buf,
17341 size_t len)
17342#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17343static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17344 struct net_device *dev,
17345 u8 *peer, u8 action_code,
17346 u8 dialog_token,
17347 u16 status_code, u32 peer_capability,
17348 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017349#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017350static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17351 struct net_device *dev,
17352 u8 *peer, u8 action_code,
17353 u8 dialog_token,
17354 u16 status_code, const u8 *buf,
17355 size_t len)
17356#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017357#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017358{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017359 hdd_adapter_t *pAdapter;
17360 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017361 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017362 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017363 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017364 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017365 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017366 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017367#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017368 u32 peer_capability = 0;
17369#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017370 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017371 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017372
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017373 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17374 if (NULL == pAdapter)
17375 {
17376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17377 "%s: Adapter is NULL",__func__);
17378 return -EINVAL;
17379 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017380 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17381 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17382 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017383
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017384 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017385 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017386 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017388 "Invalid arguments");
17389 return -EINVAL;
17390 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017391
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017392 if (pHddCtx->isLogpInProgress)
17393 {
17394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17395 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017396 wlan_hdd_tdls_set_link_status(pAdapter,
17397 peer,
17398 eTDLS_LINK_IDLE,
17399 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017400 return -EBUSY;
17401 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017402
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017403 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17404 {
17405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17406 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17407 return -EAGAIN;
17408 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017409
Hoonki Lee27511902013-03-14 18:19:06 -070017410 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017411 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017413 "%s: TDLS mode is disabled OR not enabled in FW."
17414 MAC_ADDRESS_STR " action %d declined.",
17415 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017416 return -ENOTSUPP;
17417 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017418
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017419 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17420
17421 if( NULL == pHddStaCtx )
17422 {
17423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17424 "%s: HDD station context NULL ",__func__);
17425 return -EINVAL;
17426 }
17427
17428 /* STA should be connected and authenticated
17429 * before sending any TDLS frames
17430 */
17431 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17432 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17433 {
17434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17435 "STA is not connected or unauthenticated. "
17436 "connState %u, uIsAuthenticated %u",
17437 pHddStaCtx->conn_info.connState,
17438 pHddStaCtx->conn_info.uIsAuthenticated);
17439 return -EAGAIN;
17440 }
17441
Hoonki Lee27511902013-03-14 18:19:06 -070017442 /* other than teardown frame, other mgmt frames are not sent if disabled */
17443 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17444 {
17445 /* if tdls_mode is disabled to respond to peer's request */
17446 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17447 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017449 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017450 " TDLS mode is disabled. action %d declined.",
17451 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017452
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017453 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017454 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017455
17456 if (vos_max_concurrent_connections_reached())
17457 {
17458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17459 return -EINVAL;
17460 }
Hoonki Lee27511902013-03-14 18:19:06 -070017461 }
17462
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017463 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17464 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017465 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017466 {
17467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017468 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017469 " TDLS setup is ongoing. action %d declined.",
17470 __func__, MAC_ADDR_ARRAY(peer), action_code);
17471 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017472 }
17473 }
17474
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017475 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17476 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017477 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017478 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17479 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017480 {
17481 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17482 we return error code at 'add_station()'. Hence we have this
17483 check again in addtion to add_station().
17484 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017485 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017486 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17488 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017489 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17490 __func__, MAC_ADDR_ARRAY(peer), action_code,
17491 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017492 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017493 }
17494 else
17495 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017496 /* maximum reached. tweak to send error code to peer and return
17497 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017498 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17500 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017501 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17502 __func__, MAC_ADDR_ARRAY(peer), status_code,
17503 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017504 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017505 /* fall through to send setup resp with failure status
17506 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017507 }
17508 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017509 else
17510 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017511 mutex_lock(&pHddCtx->tdls_lock);
17512 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017513 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017514 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017515 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017517 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17518 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017519 return -EPERM;
17520 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017521 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017522 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017523 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017524
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017526 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017527 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17528 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017529
Hoonki Leea34dd892013-02-05 22:56:02 -080017530 /*Except teardown responder will not be used so just make 0*/
17531 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017532 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017533 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017534
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017535 mutex_lock(&pHddCtx->tdls_lock);
17536 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017537
17538 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17539 responder = pTdlsPeer->is_responder;
17540 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017541 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017543 "%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 -070017544 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17545 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017546 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017547 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017548 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017549 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017550 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017551
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017552 /* Discard TDLS setup if peer is removed by user app */
17553 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17554 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17555 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17556 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17557
17558 mutex_lock(&pHddCtx->tdls_lock);
17559 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17560 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17561 mutex_unlock(&pHddCtx->tdls_lock);
17562 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17563 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17564 MAC_ADDR_ARRAY(peer), action_code);
17565 return -EINVAL;
17566 }
17567 mutex_unlock(&pHddCtx->tdls_lock);
17568 }
17569
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017570 /* For explicit trigger of DIS_REQ come out of BMPS for
17571 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017572 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017573 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017574 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17575 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017576 {
17577 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17578 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017580 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017581 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17582 if (status != VOS_STATUS_SUCCESS) {
17583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17584 }
Hoonki Lee14621352013-04-16 17:51:19 -070017585 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017586 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017587 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17589 }
17590 }
Hoonki Lee14621352013-04-16 17:51:19 -070017591 }
17592
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017593 /* make sure doesn't call send_mgmt() while it is pending */
17594 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17595 {
17596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017597 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017598 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017599 ret = -EBUSY;
17600 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017601 }
17602
17603 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017604 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17605
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017606 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17607 pAdapter->sessionId, peer, action_code, dialog_token,
17608 status_code, peer_capability, (tANI_U8 *)buf, len,
17609 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017610
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017611 if (VOS_STATUS_SUCCESS != status)
17612 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17614 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017615 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017616 ret = -EINVAL;
17617 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017618 }
17619
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17621 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17622 WAIT_TIME_TDLS_MGMT);
17623
Hoonki Leed37cbb32013-04-20 00:31:14 -070017624 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17625 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17626
17627 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017628 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017630 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017631 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017632 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017633
17634 if (pHddCtx->isLogpInProgress)
17635 {
17636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17637 "%s: LOGP in Progress. Ignore!!!", __func__);
17638 return -EAGAIN;
17639 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017640 if (rc <= 0)
17641 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17642 WLAN_LOG_INDICATOR_HOST_DRIVER,
17643 WLAN_LOG_REASON_HDD_TIME_OUT,
17644 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017645
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017646 ret = -EINVAL;
17647 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017648 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017649 else
17650 {
17651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17652 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17653 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17654 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017655
Gopichand Nakkala05922802013-03-14 12:23:19 -070017656 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017657 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017658 ret = max_sta_failed;
17659 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017660 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017661
Hoonki Leea34dd892013-02-05 22:56:02 -080017662 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17663 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017664 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17666 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017667 }
17668 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17669 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017670 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17672 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017673 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017674
17675 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017676
17677tx_failed:
17678 /* add_station will be called before sending TDLS_SETUP_REQ and
17679 * TDLS_SETUP_RSP and as part of add_station driver will enable
17680 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17681 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17682 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17683 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17684 */
17685
17686 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17687 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17688 wlan_hdd_tdls_check_bmps(pAdapter);
17689 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017690}
17691
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017692#if TDLS_MGMT_VERSION2
17693static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17694 u8 *peer, u8 action_code, u8 dialog_token,
17695 u16 status_code, u32 peer_capability,
17696 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017697#else /* TDLS_MGMT_VERSION2 */
17698#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17699static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17700 struct net_device *dev,
17701 const u8 *peer, u8 action_code,
17702 u8 dialog_token, u16 status_code,
17703 u32 peer_capability, bool initiator,
17704 const u8 *buf, size_t len)
17705#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17706static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17707 struct net_device *dev,
17708 const u8 *peer, u8 action_code,
17709 u8 dialog_token, u16 status_code,
17710 u32 peer_capability, const u8 *buf,
17711 size_t len)
17712#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17713static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17714 struct net_device *dev,
17715 u8 *peer, u8 action_code,
17716 u8 dialog_token,
17717 u16 status_code, u32 peer_capability,
17718 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017719#else
17720static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17721 u8 *peer, u8 action_code, u8 dialog_token,
17722 u16 status_code, const u8 *buf, size_t len)
17723#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017724#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017725{
17726 int ret;
17727
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017728 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017729#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017730 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17731 dialog_token, status_code,
17732 peer_capability, buf, len);
17733#else /* TDLS_MGMT_VERSION2 */
17734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17735 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17736 dialog_token, status_code,
17737 peer_capability, initiator,
17738 buf, len);
17739#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17740 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17741 dialog_token, status_code,
17742 peer_capability, buf, len);
17743#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17744 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17745 dialog_token, status_code,
17746 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017747#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017748 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17749 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017750#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017751#endif
17752 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017753
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017754 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017755}
Atul Mittal115287b2014-07-08 13:26:33 +053017756
17757int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17759 const u8 *peer,
17760#else
Atul Mittal115287b2014-07-08 13:26:33 +053017761 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017762#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017763 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017764 cfg80211_exttdls_callback callback)
17765{
17766
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017767 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017768 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017769 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17771 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17772 __func__, MAC_ADDR_ARRAY(peer));
17773
17774 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17775 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17776
17777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017778 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17779 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17780 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017781 return -ENOTSUPP;
17782 }
17783
17784 /* To cater the requirement of establishing the TDLS link
17785 * irrespective of the data traffic , get an entry of TDLS peer.
17786 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017787 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017788 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17789 if (pTdlsPeer == NULL) {
17790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17791 "%s: peer " MAC_ADDRESS_STR " not existing",
17792 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017793 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017794 return -EINVAL;
17795 }
17796
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017797 /* check FW TDLS Off Channel capability */
17798 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017799 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017800 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017801 {
17802 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17803 pTdlsPeer->peerParams.global_operating_class =
17804 tdls_peer_params->global_operating_class;
17805 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17806 pTdlsPeer->peerParams.min_bandwidth_kbps =
17807 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017808 /* check configured channel is valid, non dfs and
17809 * not current operating channel */
17810 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17811 tdls_peer_params->channel)) &&
17812 (pHddStaCtx) &&
17813 (tdls_peer_params->channel !=
17814 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017815 {
17816 pTdlsPeer->isOffChannelConfigured = TRUE;
17817 }
17818 else
17819 {
17820 pTdlsPeer->isOffChannelConfigured = FALSE;
17821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17822 "%s: Configured Tdls Off Channel is not valid", __func__);
17823
17824 }
17825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017826 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17827 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017828 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017829 pTdlsPeer->isOffChannelConfigured,
17830 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017831 }
17832 else
17833 {
17834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017835 "%s: TDLS off channel FW capability %d, "
17836 "host capab %d or Invalid TDLS Peer Params", __func__,
17837 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17838 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017839 }
17840
Atul Mittal115287b2014-07-08 13:26:33 +053017841 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17842
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017843 mutex_unlock(&pHddCtx->tdls_lock);
17844
Atul Mittal115287b2014-07-08 13:26:33 +053017845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17846 " %s TDLS Add Force Peer Failed",
17847 __func__);
17848 return -EINVAL;
17849 }
17850 /*EXT TDLS*/
17851
17852 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017853 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17855 " %s TDLS set callback Failed",
17856 __func__);
17857 return -EINVAL;
17858 }
17859
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017860 mutex_unlock(&pHddCtx->tdls_lock);
17861
Atul Mittal115287b2014-07-08 13:26:33 +053017862 return(0);
17863
17864}
17865
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017866int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17868 const u8 *peer
17869#else
17870 u8 *peer
17871#endif
17872)
Atul Mittal115287b2014-07-08 13:26:33 +053017873{
17874
17875 hddTdlsPeer_t *pTdlsPeer;
17876 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017877
Atul Mittal115287b2014-07-08 13:26:33 +053017878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17879 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17880 __func__, MAC_ADDR_ARRAY(peer));
17881
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017882 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17884 return -EINVAL;
17885 }
17886
Atul Mittal115287b2014-07-08 13:26:33 +053017887 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17888 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17889
17890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017891 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17892 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17893 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017894 return -ENOTSUPP;
17895 }
17896
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017897 mutex_lock(&pHddCtx->tdls_lock);
17898 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017899
17900 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017901 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017902 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017903 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017904 __func__, MAC_ADDR_ARRAY(peer));
17905 return -EINVAL;
17906 }
17907 else {
17908 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17909 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017910 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
17911 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017912 /* if channel switch is configured, reset
17913 the channel for this peer */
17914 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17915 {
17916 pTdlsPeer->peerParams.channel = 0;
17917 pTdlsPeer->isOffChannelConfigured = FALSE;
17918 }
Atul Mittal115287b2014-07-08 13:26:33 +053017919 }
17920
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017921 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017922 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017924 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017925 }
Atul Mittal115287b2014-07-08 13:26:33 +053017926
17927 /*EXT TDLS*/
17928
17929 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017930 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17932 " %s TDLS set callback Failed",
17933 __func__);
17934 return -EINVAL;
17935 }
Atul Mittal115287b2014-07-08 13:26:33 +053017936
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017937 mutex_unlock(&pHddCtx->tdls_lock);
17938
17939 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017940}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017941static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017942#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17943 const u8 *peer,
17944#else
17945 u8 *peer,
17946#endif
17947 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017948{
17949 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17950 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017951 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017952 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017953
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017954 ENTER();
17955
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017956 if (!pAdapter) {
17957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17958 return -EINVAL;
17959 }
17960
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17962 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17963 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017964 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017965 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017967 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017968 return -EINVAL;
17969 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017970
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017971 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017972 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017973 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017974 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017975 }
17976
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017977
17978 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017979 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017980 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017982 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17983 "Cannot process TDLS commands",
17984 pHddCtx->cfg_ini->fEnableTDLSSupport,
17985 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017986 return -ENOTSUPP;
17987 }
17988
17989 switch (oper) {
17990 case NL80211_TDLS_ENABLE_LINK:
17991 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017992 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017993 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053017994 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
17995 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053017996 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017997 tANI_U16 numCurrTdlsPeers = 0;
17998 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017999 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018000 tSirMacAddr peerMac;
18001 int channel;
18002 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018003
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18005 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18006 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018007
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018008 mutex_lock(&pHddCtx->tdls_lock);
18009 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018010 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018011 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018012 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18014 " (oper %d) not exsting. ignored",
18015 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18016 return -EINVAL;
18017 }
18018
18019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18020 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18021 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18022 "NL80211_TDLS_ENABLE_LINK");
18023
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018024 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18025 {
18026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18027 MAC_ADDRESS_STR " failed",
18028 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018029 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018030 return -EINVAL;
18031 }
18032
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053018033 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018034 /* before starting tdls connection, set tdls
18035 * off channel established status to default value */
18036 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018037
18038 mutex_unlock(&pHddCtx->tdls_lock);
18039
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018040 /* TDLS Off Channel, Disable tdls channel switch,
18041 when there are more than one tdls link */
18042 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018043 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018044 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018045 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018046 /* get connected peer and send disable tdls off chan */
18047 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018048 if ((connPeer) &&
18049 (connPeer->isOffChannelSupported == TRUE) &&
18050 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018051 {
18052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18053 "%s: More then one peer connected, Disable "
18054 "TDLS channel switch", __func__);
18055
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018056 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018057 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18058 channel = connPeer->peerParams.channel;
18059
18060 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018061
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018062 ret = sme_SendTdlsChanSwitchReq(
18063 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018064 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018065 peerMac,
18066 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018067 TDLS_OFF_CHANNEL_BW_OFFSET,
18068 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018069 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018070 hddLog(VOS_TRACE_LEVEL_ERROR,
18071 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018072 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018073 }
18074 else
18075 {
18076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18077 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018078 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018079 "isOffChannelConfigured %d",
18080 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018081 (connPeer ? (connPeer->isOffChannelSupported)
18082 : -1),
18083 (connPeer ? (connPeer->isOffChannelConfigured)
18084 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018085 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018086 }
18087 }
18088
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018089 mutex_lock(&pHddCtx->tdls_lock);
18090 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18091 if ( NULL == pTdlsPeer ) {
18092 mutex_unlock(&pHddCtx->tdls_lock);
18093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18094 "%s: " MAC_ADDRESS_STR
18095 " (oper %d) peer got freed in other context. ignored",
18096 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18097 return -EINVAL;
18098 }
18099 peer_status = pTdlsPeer->link_status;
18100 mutex_unlock(&pHddCtx->tdls_lock);
18101
18102 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018103 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018104 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018105
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018106 if (0 != wlan_hdd_tdls_get_link_establish_params(
18107 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018109 return -EINVAL;
18110 }
18111 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018112
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018113 ret = sme_SendTdlsLinkEstablishParams(
18114 WLAN_HDD_GET_HAL_CTX(pAdapter),
18115 pAdapter->sessionId, peer,
18116 &tdlsLinkEstablishParams);
18117 if (ret != VOS_STATUS_SUCCESS) {
18118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18119 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018120 /* Send TDLS peer UAPSD capabilities to the firmware and
18121 * register with the TL on after the response for this operation
18122 * is received .
18123 */
18124 ret = wait_for_completion_interruptible_timeout(
18125 &pAdapter->tdls_link_establish_req_comp,
18126 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018127
18128 mutex_lock(&pHddCtx->tdls_lock);
18129 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18130 if ( NULL == pTdlsPeer ) {
18131 mutex_unlock(&pHddCtx->tdls_lock);
18132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18133 "%s %d: " MAC_ADDRESS_STR
18134 " (oper %d) peer got freed in other context. ignored",
18135 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18136 (int)oper);
18137 return -EINVAL;
18138 }
18139 peer_status = pTdlsPeer->link_status;
18140 mutex_unlock(&pHddCtx->tdls_lock);
18141
18142 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018143 {
18144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018145 FL("Link Establish Request Failed Status %ld"),
18146 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018147 return -EINVAL;
18148 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018149 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018150
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018151 mutex_lock(&pHddCtx->tdls_lock);
18152 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18153 if ( NULL == pTdlsPeer ) {
18154 mutex_unlock(&pHddCtx->tdls_lock);
18155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18156 "%s: " MAC_ADDRESS_STR
18157 " (oper %d) peer got freed in other context. ignored",
18158 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18159 return -EINVAL;
18160 }
18161
Atul Mittal115287b2014-07-08 13:26:33 +053018162 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18163 eTDLS_LINK_CONNECTED,
18164 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018165 staDesc.ucSTAId = pTdlsPeer->staId;
18166 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018167
18168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18169 "%s: tdlsLinkEstablishParams of peer "
18170 MAC_ADDRESS_STR "uapsdQueues: %d"
18171 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18172 "isResponder: %d peerstaId: %d",
18173 __func__,
18174 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18175 tdlsLinkEstablishParams.uapsdQueues,
18176 tdlsLinkEstablishParams.qos,
18177 tdlsLinkEstablishParams.maxSp,
18178 tdlsLinkEstablishParams.isBufSta,
18179 tdlsLinkEstablishParams.isOffChannelSupported,
18180 tdlsLinkEstablishParams.isResponder,
18181 pTdlsPeer->staId);
18182
18183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18184 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18185 __func__,
18186 staDesc.ucSTAId,
18187 staDesc.ucQosEnabled);
18188
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018189 ret = WLANTL_UpdateTdlsSTAClient(
18190 pHddCtx->pvosContext,
18191 &staDesc);
18192 if (ret != VOS_STATUS_SUCCESS) {
18193 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18194 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018195
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018196 /* Mark TDLS client Authenticated .*/
18197 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18198 pTdlsPeer->staId,
18199 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018200 if (VOS_STATUS_SUCCESS == status)
18201 {
Hoonki Lee14621352013-04-16 17:51:19 -070018202 if (pTdlsPeer->is_responder == 0)
18203 {
18204 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018205 tdlsConnInfo_t *tdlsInfo;
18206
18207 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18208
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018209 if (!vos_timer_is_initialized(
18210 &pTdlsPeer->initiatorWaitTimeoutTimer))
18211 {
18212 /* Initialize initiator wait callback */
18213 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018214 &pTdlsPeer->initiatorWaitTimeoutTimer,
18215 VOS_TIMER_TYPE_SW,
18216 wlan_hdd_tdls_initiator_wait_cb,
18217 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018218 }
Hoonki Lee14621352013-04-16 17:51:19 -070018219 wlan_hdd_tdls_timer_restart(pAdapter,
18220 &pTdlsPeer->initiatorWaitTimeoutTimer,
18221 WAIT_TIME_TDLS_INITIATOR);
18222 /* suspend initiator TX until it receives direct packet from the
18223 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018224 ret = WLANTL_SuspendDataTx(
18225 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18226 &staId, NULL);
18227 if (ret != VOS_STATUS_SUCCESS) {
18228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18229 }
Hoonki Lee14621352013-04-16 17:51:19 -070018230 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018231
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018232 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018233 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018234 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018235 suppChannelLen =
18236 tdlsLinkEstablishParams.supportedChannelsLen;
18237
18238 if ((suppChannelLen > 0) &&
18239 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18240 {
18241 tANI_U8 suppPeerChannel = 0;
18242 int i = 0;
18243 for (i = 0U; i < suppChannelLen; i++)
18244 {
18245 suppPeerChannel =
18246 tdlsLinkEstablishParams.supportedChannels[i];
18247
18248 pTdlsPeer->isOffChannelSupported = FALSE;
18249 if (suppPeerChannel ==
18250 pTdlsPeer->peerParams.channel)
18251 {
18252 pTdlsPeer->isOffChannelSupported = TRUE;
18253 break;
18254 }
18255 }
18256 }
18257 else
18258 {
18259 pTdlsPeer->isOffChannelSupported = FALSE;
18260 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018261 }
18262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18263 "%s: TDLS channel switch request for channel "
18264 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018265 "%d isOffChannelSupported %d", __func__,
18266 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018267 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018268 suppChannelLen,
18269 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018270
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018271 /* TDLS Off Channel, Enable tdls channel switch,
18272 when their is only one tdls link and it supports */
18273 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18274 if ((numCurrTdlsPeers == 1) &&
18275 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18276 (TRUE == pTdlsPeer->isOffChannelConfigured))
18277 {
18278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18279 "%s: Send TDLS channel switch request for channel %d",
18280 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018281
18282 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018283 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18284 channel = pTdlsPeer->peerParams.channel;
18285
18286 mutex_unlock(&pHddCtx->tdls_lock);
18287
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018288 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18289 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018290 peerMac,
18291 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018292 TDLS_OFF_CHANNEL_BW_OFFSET,
18293 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018294 if (ret != VOS_STATUS_SUCCESS) {
18295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18296 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018297 }
18298 else
18299 {
18300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18301 "%s: TDLS channel switch request not sent"
18302 " numCurrTdlsPeers %d "
18303 "isOffChannelSupported %d "
18304 "isOffChannelConfigured %d",
18305 __func__, numCurrTdlsPeers,
18306 pTdlsPeer->isOffChannelSupported,
18307 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018308 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018309 }
18310
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018311 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018312 else
18313 mutex_unlock(&pHddCtx->tdls_lock);
18314
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018315 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018316
18317 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018318 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18319 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018320 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018321 int ac;
18322 uint8 ucAc[4] = { WLANTL_AC_VO,
18323 WLANTL_AC_VI,
18324 WLANTL_AC_BK,
18325 WLANTL_AC_BE };
18326 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18327 for(ac=0; ac < 4; ac++)
18328 {
18329 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18330 pTdlsPeer->staId, ucAc[ac],
18331 tlTid[ac], tlTid[ac], 0, 0,
18332 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018333 if (status != VOS_STATUS_SUCCESS) {
18334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18335 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018336 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018337 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018338 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018339
Bhargav Shah66896792015-10-01 18:17:37 +053018340 /* stop TCP delack timer if TDLS is enable */
18341 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18342 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018343 hdd_wlan_tdls_enable_link_event(peer,
18344 pTdlsPeer->isOffChannelSupported,
18345 pTdlsPeer->isOffChannelConfigured,
18346 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018347 }
18348 break;
18349 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018350 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018351 tANI_U16 numCurrTdlsPeers = 0;
18352 hddTdlsPeer_t *connPeer = NULL;
18353
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18355 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18356 __func__, MAC_ADDR_ARRAY(peer));
18357
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018358 mutex_lock(&pHddCtx->tdls_lock);
18359 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018360
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018361
Sunil Dutt41de4e22013-11-14 18:09:02 +053018362 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018363 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18365 " (oper %d) not exsting. ignored",
18366 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18367 return -EINVAL;
18368 }
18369
18370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18371 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18372 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18373 "NL80211_TDLS_DISABLE_LINK");
18374
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018375 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018376 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018377 long status;
18378
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018379 /* set tdls off channel status to false for this peer */
18380 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018381 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18382 eTDLS_LINK_TEARING,
18383 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18384 eTDLS_LINK_UNSPECIFIED:
18385 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018386 mutex_unlock(&pHddCtx->tdls_lock);
18387
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018388 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18389
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018390 status = sme_DeleteTdlsPeerSta(
18391 WLAN_HDD_GET_HAL_CTX(pAdapter),
18392 pAdapter->sessionId, peer );
18393 if (status != VOS_STATUS_SUCCESS) {
18394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18395 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018396
18397 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18398 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018399
18400 mutex_lock(&pHddCtx->tdls_lock);
18401 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18402 if ( NULL == pTdlsPeer ) {
18403 mutex_unlock(&pHddCtx->tdls_lock);
18404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18405 " peer was freed in other context",
18406 __func__, MAC_ADDR_ARRAY(peer));
18407 return -EINVAL;
18408 }
18409
Atul Mittal271a7652014-09-12 13:18:22 +053018410 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018411 eTDLS_LINK_IDLE,
18412 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018413 mutex_unlock(&pHddCtx->tdls_lock);
18414
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018415 if (status <= 0)
18416 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18418 "%s: Del station failed status %ld",
18419 __func__, status);
18420 return -EPERM;
18421 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018422
18423 /* TDLS Off Channel, Enable tdls channel switch,
18424 when their is only one tdls link and it supports */
18425 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18426 if (numCurrTdlsPeers == 1)
18427 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018428 tSirMacAddr peerMac;
18429 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018430
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018431 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018432 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018433
18434 if (connPeer == NULL) {
18435 mutex_unlock(&pHddCtx->tdls_lock);
18436 hddLog(VOS_TRACE_LEVEL_ERROR,
18437 "%s connPeer is NULL", __func__);
18438 return -EINVAL;
18439 }
18440
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018441 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18442 channel = connPeer->peerParams.channel;
18443
18444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18445 "%s: TDLS channel switch "
18446 "isOffChannelSupported %d "
18447 "isOffChannelConfigured %d "
18448 "isOffChannelEstablished %d",
18449 __func__,
18450 (connPeer ? connPeer->isOffChannelSupported : -1),
18451 (connPeer ? connPeer->isOffChannelConfigured : -1),
18452 (connPeer ? connPeer->isOffChannelEstablished : -1));
18453
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018454 if ((connPeer) &&
18455 (connPeer->isOffChannelSupported == TRUE) &&
18456 (connPeer->isOffChannelConfigured == TRUE))
18457 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018458 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018459 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018460 status = sme_SendTdlsChanSwitchReq(
18461 WLAN_HDD_GET_HAL_CTX(pAdapter),
18462 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018463 peerMac,
18464 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018465 TDLS_OFF_CHANNEL_BW_OFFSET,
18466 TDLS_CHANNEL_SWITCH_ENABLE);
18467 if (status != VOS_STATUS_SUCCESS) {
18468 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18469 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018470 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018471 else
18472 mutex_unlock(&pHddCtx->tdls_lock);
18473 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018474 else
18475 {
18476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18477 "%s: TDLS channel switch request not sent "
18478 "numCurrTdlsPeers %d ",
18479 __func__, numCurrTdlsPeers);
18480 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018481 }
18482 else
18483 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018484 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18486 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018487 }
Bhargav Shah66896792015-10-01 18:17:37 +053018488 if (numCurrTdlsPeers == 0) {
18489 /* start TCP delack timer if TDLS is disable */
18490 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18491 hdd_manage_delack_timer(pHddCtx);
18492 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018493 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018494 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018495 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018496 {
Atul Mittal115287b2014-07-08 13:26:33 +053018497 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018498
Atul Mittal115287b2014-07-08 13:26:33 +053018499 if (0 != status)
18500 {
18501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018502 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018503 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018504 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018505 break;
18506 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018507 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018508 {
Atul Mittal115287b2014-07-08 13:26:33 +053018509 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18510 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018511 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018512 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018513
Atul Mittal115287b2014-07-08 13:26:33 +053018514 if (0 != status)
18515 {
18516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018517 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018518 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018519 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018520 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018521 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018522 case NL80211_TDLS_DISCOVERY_REQ:
18523 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018525 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018526 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018527 return -ENOTSUPP;
18528 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18530 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018531 return -ENOTSUPP;
18532 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018533
18534 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018535 return 0;
18536}
Chilam NG571c65a2013-01-19 12:27:36 +053018537
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018538static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18540 const u8 *peer,
18541#else
18542 u8 *peer,
18543#endif
18544 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018545{
18546 int ret;
18547
18548 vos_ssr_protect(__func__);
18549 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18550 vos_ssr_unprotect(__func__);
18551
18552 return ret;
18553}
18554
Chilam NG571c65a2013-01-19 12:27:36 +053018555int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18556 struct net_device *dev, u8 *peer)
18557{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018558 hddLog(VOS_TRACE_LEVEL_INFO,
18559 "tdls send discover req: "MAC_ADDRESS_STR,
18560 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018561#if TDLS_MGMT_VERSION2
18562 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18563 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18564#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18566 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18567 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18568#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18569 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18570 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18571#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18572 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18573 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18574#else
Chilam NG571c65a2013-01-19 12:27:36 +053018575 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18576 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018577#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018578#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018579}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018580#endif
18581
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018582#ifdef WLAN_FEATURE_GTK_OFFLOAD
18583/*
18584 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18585 * Callback rountine called upon receiving response for
18586 * get offload info
18587 */
18588void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18589 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18590{
18591
18592 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018593 tANI_U8 tempReplayCounter[8];
18594 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018595
18596 ENTER();
18597
18598 if (NULL == pAdapter)
18599 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018601 "%s: HDD adapter is Null", __func__);
18602 return ;
18603 }
18604
18605 if (NULL == pGtkOffloadGetInfoRsp)
18606 {
18607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18608 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18609 return ;
18610 }
18611
18612 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18613 {
18614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18615 "%s: wlan Failed to get replay counter value",
18616 __func__);
18617 return ;
18618 }
18619
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018620 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18621 /* Update replay counter */
18622 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18623 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18624
18625 {
18626 /* changing from little to big endian since supplicant
18627 * works on big endian format
18628 */
18629 int i;
18630 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18631
18632 for (i = 0; i < 8; i++)
18633 {
18634 tempReplayCounter[7-i] = (tANI_U8)p[i];
18635 }
18636 }
18637
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018638 /* Update replay counter to NL */
18639 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018640 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018641}
18642
18643/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018644 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018645 * This function is used to offload GTK rekeying job to the firmware.
18646 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018647int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018648 struct cfg80211_gtk_rekey_data *data)
18649{
18650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18651 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18652 hdd_station_ctx_t *pHddStaCtx;
18653 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018654 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018655 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018656 eHalStatus status = eHAL_STATUS_FAILURE;
18657
18658 ENTER();
18659
18660 if (NULL == pAdapter)
18661 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018663 "%s: HDD adapter is Null", __func__);
18664 return -ENODEV;
18665 }
18666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18668 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18669 pAdapter->sessionId, pAdapter->device_mode));
18670
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018671 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018672 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018673 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018674 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018675 }
18676
18677 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18678 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18679 if (NULL == hHal)
18680 {
18681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18682 "%s: HAL context is Null!!!", __func__);
18683 return -EAGAIN;
18684 }
18685
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018686 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18687 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18688 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18689 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018690 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018691 {
18692 /* changing from big to little endian since driver
18693 * works on little endian format
18694 */
18695 tANI_U8 *p =
18696 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18697 int i;
18698
18699 for (i = 0; i < 8; i++)
18700 {
18701 p[7-i] = data->replay_ctr[i];
18702 }
18703 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018704
18705 if (TRUE == pHddCtx->hdd_wlan_suspended)
18706 {
18707 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018708 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18709 sizeof (tSirGtkOffloadParams));
18710 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018711 pAdapter->sessionId);
18712
18713 if (eHAL_STATUS_SUCCESS != status)
18714 {
18715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18716 "%s: sme_SetGTKOffload failed, returned %d",
18717 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018718
18719 /* Need to clear any trace of key value in the memory.
18720 * Thus zero out the memory even though it is local
18721 * variable.
18722 */
18723 vos_mem_zero(&hddGtkOffloadReqParams,
18724 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018725 return status;
18726 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18728 "%s: sme_SetGTKOffload successfull", __func__);
18729 }
18730 else
18731 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18733 "%s: wlan not suspended GTKOffload request is stored",
18734 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018735 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018736
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018737 /* Need to clear any trace of key value in the memory.
18738 * Thus zero out the memory even though it is local
18739 * variable.
18740 */
18741 vos_mem_zero(&hddGtkOffloadReqParams,
18742 sizeof(hddGtkOffloadReqParams));
18743
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018744 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018745 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018746}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018747
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018748int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18749 struct cfg80211_gtk_rekey_data *data)
18750{
18751 int ret;
18752
18753 vos_ssr_protect(__func__);
18754 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18755 vos_ssr_unprotect(__func__);
18756
18757 return ret;
18758}
18759#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018760/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018761 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018762 * This function is used to set access control policy
18763 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018764static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18765 struct net_device *dev,
18766 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018767{
18768 int i;
18769 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18770 hdd_hostapd_state_t *pHostapdState;
18771 tsap_Config_t *pConfig;
18772 v_CONTEXT_t pVosContext = NULL;
18773 hdd_context_t *pHddCtx;
18774 int status;
18775
18776 ENTER();
18777
18778 if (NULL == pAdapter)
18779 {
18780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18781 "%s: HDD adapter is Null", __func__);
18782 return -ENODEV;
18783 }
18784
18785 if (NULL == params)
18786 {
18787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18788 "%s: params is Null", __func__);
18789 return -EINVAL;
18790 }
18791
18792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18793 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018794 if (0 != status)
18795 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018796 return status;
18797 }
18798
18799 pVosContext = pHddCtx->pvosContext;
18800 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18801
18802 if (NULL == pHostapdState)
18803 {
18804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18805 "%s: pHostapdState is Null", __func__);
18806 return -EINVAL;
18807 }
18808
18809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18810 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018811 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18812 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18813 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018814
18815 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18816 {
18817 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18818
18819 /* default value */
18820 pConfig->num_accept_mac = 0;
18821 pConfig->num_deny_mac = 0;
18822
18823 /**
18824 * access control policy
18825 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18826 * listed in hostapd.deny file.
18827 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18828 * listed in hostapd.accept file.
18829 */
18830 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18831 {
18832 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18833 }
18834 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18835 {
18836 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18837 }
18838 else
18839 {
18840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18841 "%s:Acl Policy : %d is not supported",
18842 __func__, params->acl_policy);
18843 return -ENOTSUPP;
18844 }
18845
18846 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18847 {
18848 pConfig->num_accept_mac = params->n_acl_entries;
18849 for (i = 0; i < params->n_acl_entries; i++)
18850 {
18851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18852 "** Add ACL MAC entry %i in WhiletList :"
18853 MAC_ADDRESS_STR, i,
18854 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18855
18856 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18857 sizeof(qcmacaddr));
18858 }
18859 }
18860 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18861 {
18862 pConfig->num_deny_mac = params->n_acl_entries;
18863 for (i = 0; i < params->n_acl_entries; i++)
18864 {
18865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18866 "** Add ACL MAC entry %i in BlackList :"
18867 MAC_ADDRESS_STR, i,
18868 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18869
18870 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18871 sizeof(qcmacaddr));
18872 }
18873 }
18874
18875 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18876 {
18877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18878 "%s: SAP Set Mac Acl fail", __func__);
18879 return -EINVAL;
18880 }
18881 }
18882 else
18883 {
18884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018885 "%s: Invalid device_mode = %s (%d)",
18886 __func__, hdd_device_modetoString(pAdapter->device_mode),
18887 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018888 return -EINVAL;
18889 }
18890
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018891 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018892 return 0;
18893}
18894
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018895static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18896 struct net_device *dev,
18897 const struct cfg80211_acl_data *params)
18898{
18899 int ret;
18900 vos_ssr_protect(__func__);
18901 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18902 vos_ssr_unprotect(__func__);
18903
18904 return ret;
18905}
18906
Leo Chang9056f462013-08-01 19:21:11 -070018907#ifdef WLAN_NL80211_TESTMODE
18908#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018909void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018910(
18911 void *pAdapter,
18912 void *indCont
18913)
18914{
Leo Changd9df8aa2013-09-26 13:32:26 -070018915 tSirLPHBInd *lphbInd;
18916 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018917 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018918
18919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018920 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018921
c_hpothu73f35e62014-04-18 13:40:08 +053018922 if (pAdapter == NULL)
18923 {
18924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18925 "%s: pAdapter is NULL\n",__func__);
18926 return;
18927 }
18928
Leo Chang9056f462013-08-01 19:21:11 -070018929 if (NULL == indCont)
18930 {
18931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018932 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018933 return;
18934 }
18935
c_hpothu73f35e62014-04-18 13:40:08 +053018936 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018937 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018938 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018939 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018940 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018941 GFP_ATOMIC);
18942 if (!skb)
18943 {
18944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18945 "LPHB timeout, NL buffer alloc fail");
18946 return;
18947 }
18948
Leo Changac3ba772013-10-07 09:47:04 -070018949 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018950 {
18951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18952 "WLAN_HDD_TM_ATTR_CMD put fail");
18953 goto nla_put_failure;
18954 }
Leo Changac3ba772013-10-07 09:47:04 -070018955 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018956 {
18957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18958 "WLAN_HDD_TM_ATTR_TYPE put fail");
18959 goto nla_put_failure;
18960 }
Leo Changac3ba772013-10-07 09:47:04 -070018961 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018962 sizeof(tSirLPHBInd), lphbInd))
18963 {
18964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18965 "WLAN_HDD_TM_ATTR_DATA put fail");
18966 goto nla_put_failure;
18967 }
Leo Chang9056f462013-08-01 19:21:11 -070018968 cfg80211_testmode_event(skb, GFP_ATOMIC);
18969 return;
18970
18971nla_put_failure:
18972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18973 "NLA Put fail");
18974 kfree_skb(skb);
18975
18976 return;
18977}
18978#endif /* FEATURE_WLAN_LPHB */
18979
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018980static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018981{
18982 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18983 int err = 0;
18984#ifdef FEATURE_WLAN_LPHB
18985 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018986 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018987
18988 ENTER();
18989
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018990 err = wlan_hdd_validate_context(pHddCtx);
18991 if (0 != err)
18992 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018993 return err;
18994 }
Leo Chang9056f462013-08-01 19:21:11 -070018995#endif /* FEATURE_WLAN_LPHB */
18996
18997 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18998 if (err)
18999 {
19000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19001 "%s Testmode INV ATTR", __func__);
19002 return err;
19003 }
19004
19005 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19006 {
19007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19008 "%s Testmode INV CMD", __func__);
19009 return -EINVAL;
19010 }
19011
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019012 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19013 TRACE_CODE_HDD_CFG80211_TESTMODE,
19014 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019015 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19016 {
19017#ifdef FEATURE_WLAN_LPHB
19018 /* Low Power Heartbeat configuration request */
19019 case WLAN_HDD_TM_CMD_WLAN_HB:
19020 {
19021 int buf_len;
19022 void *buf;
19023 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019024 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019025
19026 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19027 {
19028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19029 "%s Testmode INV DATA", __func__);
19030 return -EINVAL;
19031 }
19032
19033 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19034 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019035
19036 hb_params_temp =(tSirLPHBReq *)buf;
19037 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19038 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19039 return -EINVAL;
19040
Leo Chang9056f462013-08-01 19:21:11 -070019041 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19042 if (NULL == hb_params)
19043 {
19044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19045 "%s Request Buffer Alloc Fail", __func__);
19046 return -EINVAL;
19047 }
19048
19049 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019050 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19051 hb_params,
19052 wlan_hdd_cfg80211_lphb_ind_handler);
19053 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019054 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19056 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019057 vos_mem_free(hb_params);
19058 }
Leo Chang9056f462013-08-01 19:21:11 -070019059 return 0;
19060 }
19061#endif /* FEATURE_WLAN_LPHB */
19062 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19064 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019065 return -EOPNOTSUPP;
19066 }
19067
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019068 EXIT();
19069 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019070}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019071
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019072static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19074 struct wireless_dev *wdev,
19075#endif
19076 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019077{
19078 int ret;
19079
19080 vos_ssr_protect(__func__);
19081 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19082 vos_ssr_unprotect(__func__);
19083
19084 return ret;
19085}
Leo Chang9056f462013-08-01 19:21:11 -070019086#endif /* CONFIG_NL80211_TESTMODE */
19087
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019088static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019089 struct net_device *dev,
19090 int idx, struct survey_info *survey)
19091{
19092 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19093 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019094 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019095 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019096 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019097 v_S7_t snr,rssi;
19098 int status, i, j, filled = 0;
19099
19100 ENTER();
19101
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019102 if (NULL == pAdapter)
19103 {
19104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19105 "%s: HDD adapter is Null", __func__);
19106 return -ENODEV;
19107 }
19108
19109 if (NULL == wiphy)
19110 {
19111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19112 "%s: wiphy is Null", __func__);
19113 return -ENODEV;
19114 }
19115
19116 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19117 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019118 if (0 != status)
19119 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019120 return status;
19121 }
19122
Mihir Sheted9072e02013-08-21 17:02:29 +053019123 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19124
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019125 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019126 0 != pAdapter->survey_idx ||
19127 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019128 {
19129 /* The survey dump ops when implemented completely is expected to
19130 * return a survey of all channels and the ops is called by the
19131 * kernel with incremental values of the argument 'idx' till it
19132 * returns -ENONET. But we can only support the survey for the
19133 * operating channel for now. survey_idx is used to track
19134 * that the ops is called only once and then return -ENONET for
19135 * the next iteration
19136 */
19137 pAdapter->survey_idx = 0;
19138 return -ENONET;
19139 }
19140
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019141 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19142 {
19143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19144 "%s: Roaming in progress, hence return ", __func__);
19145 return -ENONET;
19146 }
19147
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019148 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19149
19150 wlan_hdd_get_snr(pAdapter, &snr);
19151 wlan_hdd_get_rssi(pAdapter, &rssi);
19152
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019153 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19154 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19155 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019156 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19157 hdd_wlan_get_freq(channel, &freq);
19158
19159
19160 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19161 {
19162 if (NULL == wiphy->bands[i])
19163 {
19164 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19165 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19166 continue;
19167 }
19168
19169 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19170 {
19171 struct ieee80211_supported_band *band = wiphy->bands[i];
19172
19173 if (band->channels[j].center_freq == (v_U16_t)freq)
19174 {
19175 survey->channel = &band->channels[j];
19176 /* The Rx BDs contain SNR values in dB for the received frames
19177 * while the supplicant expects noise. So we calculate and
19178 * return the value of noise (dBm)
19179 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19180 */
19181 survey->noise = rssi - snr;
19182 survey->filled = SURVEY_INFO_NOISE_DBM;
19183 filled = 1;
19184 }
19185 }
19186 }
19187
19188 if (filled)
19189 pAdapter->survey_idx = 1;
19190 else
19191 {
19192 pAdapter->survey_idx = 0;
19193 return -ENONET;
19194 }
19195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019196 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019197 return 0;
19198}
19199
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019200static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19201 struct net_device *dev,
19202 int idx, struct survey_info *survey)
19203{
19204 int ret;
19205
19206 vos_ssr_protect(__func__);
19207 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19208 vos_ssr_unprotect(__func__);
19209
19210 return ret;
19211}
19212
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019213/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019214 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019215 * this is called when cfg80211 driver resume
19216 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19217 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019218int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019219{
19220 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19221 hdd_adapter_t *pAdapter;
19222 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19223 VOS_STATUS status = VOS_STATUS_SUCCESS;
19224
19225 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019226
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019227 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019228 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019229 return 0;
19230 }
19231
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019232 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19233 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019234 spin_lock(&pHddCtx->schedScan_lock);
19235 pHddCtx->isWiphySuspended = FALSE;
19236 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19237 {
19238 spin_unlock(&pHddCtx->schedScan_lock);
19239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19240 "%s: Return resume is not due to PNO indication", __func__);
19241 return 0;
19242 }
19243 // Reset flag to avoid updatating cfg80211 data old results again
19244 pHddCtx->isSchedScanUpdatePending = FALSE;
19245 spin_unlock(&pHddCtx->schedScan_lock);
19246
19247 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19248
19249 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19250 {
19251 pAdapter = pAdapterNode->pAdapter;
19252 if ( (NULL != pAdapter) &&
19253 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19254 {
19255 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019256 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19258 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019259 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019260 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019261 {
19262 /* Acquire wakelock to handle the case where APP's tries to
19263 * suspend immediately after updating the scan results. Whis
19264 * results in app's is in suspended state and not able to
19265 * process the connect request to AP
19266 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019267 hdd_prevent_suspend_timeout(2000,
19268 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019269 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019270 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019271
19272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19273 "%s : cfg80211 scan result database updated", __func__);
19274
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019275 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019276 return 0;
19277
19278 }
19279 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19280 pAdapterNode = pNext;
19281 }
19282
19283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19284 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019285 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019286 return 0;
19287}
19288
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019289int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19290{
19291 int ret;
19292
19293 vos_ssr_protect(__func__);
19294 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19295 vos_ssr_unprotect(__func__);
19296
19297 return ret;
19298}
19299
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019300/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019301 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019302 * this is called when cfg80211 driver suspends
19303 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019304int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019305 struct cfg80211_wowlan *wow)
19306{
19307 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019308 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019309
19310 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019311
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019312 ret = wlan_hdd_validate_context(pHddCtx);
19313 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019314 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019315 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019316 }
19317
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019318
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019319 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19320 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19321 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019322 pHddCtx->isWiphySuspended = TRUE;
19323
19324 EXIT();
19325
19326 return 0;
19327}
19328
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019329int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19330 struct cfg80211_wowlan *wow)
19331{
19332 int ret;
19333
19334 vos_ssr_protect(__func__);
19335 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19336 vos_ssr_unprotect(__func__);
19337
19338 return ret;
19339}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019340
19341#ifdef FEATURE_OEM_DATA_SUPPORT
19342static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019343 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019344{
19345 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19346
19347 ENTER();
19348
19349 if (wlan_hdd_validate_context(pHddCtx)) {
19350 return;
19351 }
19352 if (!pMsg)
19353 {
19354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19355 return;
19356 }
19357
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019358 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019359
19360 EXIT();
19361 return;
19362
19363}
19364
19365void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019366 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019367{
19368 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19369
19370 ENTER();
19371
19372 if (wlan_hdd_validate_context(pHddCtx)) {
19373 return;
19374 }
19375
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019376 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019377
19378 switch(evType) {
19379 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019380 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019381 break;
19382 default:
19383 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19384 break;
19385 }
19386 EXIT();
19387}
19388#endif
19389
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19391 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019392/**
19393 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19394 * @wiphy: Pointer to wiphy
19395 * @wdev: Pointer to wireless device structure
19396 *
19397 * This function is used to abort an ongoing scan
19398 *
19399 * Return: None
19400 */
19401static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19402 struct wireless_dev *wdev)
19403{
19404 struct net_device *dev = wdev->netdev;
19405 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19406 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19407 int ret;
19408
19409 ENTER();
19410
19411 if (NULL == adapter) {
19412 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19413 return;
19414 }
19415
19416 ret = wlan_hdd_validate_context(hdd_ctx);
19417 if (0 != ret)
19418 return;
19419
19420 wlan_hdd_scan_abort(adapter);
19421
19422 return;
19423}
19424
19425/**
19426 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19427 * @wiphy: Pointer to wiphy
19428 * @wdev: Pointer to wireless device structure
19429 *
19430 * Return: None
19431 */
19432void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19433 struct wireless_dev *wdev)
19434{
19435 vos_ssr_protect(__func__);
19436 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19437 vos_ssr_unprotect(__func__);
19438
19439 return;
19440}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019441#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019442
Jeff Johnson295189b2012-06-20 16:38:30 -070019443/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019444static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019445{
19446 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19447 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19448 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19449 .change_station = wlan_hdd_change_station,
19450#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19451 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19452 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19453 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019454#else
19455 .start_ap = wlan_hdd_cfg80211_start_ap,
19456 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19457 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019458#endif
19459 .change_bss = wlan_hdd_cfg80211_change_bss,
19460 .add_key = wlan_hdd_cfg80211_add_key,
19461 .get_key = wlan_hdd_cfg80211_get_key,
19462 .del_key = wlan_hdd_cfg80211_del_key,
19463 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019464#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019465 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019466#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019467 .scan = wlan_hdd_cfg80211_scan,
19468 .connect = wlan_hdd_cfg80211_connect,
19469 .disconnect = wlan_hdd_cfg80211_disconnect,
19470 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19471 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19472 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19473 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19474 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019475 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19476 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019477 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019478#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19479 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19480 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19481 .set_txq_params = wlan_hdd_set_txq_params,
19482#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019483 .get_station = wlan_hdd_cfg80211_get_station,
19484 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19485 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019486 .add_station = wlan_hdd_cfg80211_add_station,
19487#ifdef FEATURE_WLAN_LFR
19488 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19489 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19490 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19491#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019492#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19493 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19494#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019495#ifdef FEATURE_WLAN_TDLS
19496 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19497 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19498#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019499#ifdef WLAN_FEATURE_GTK_OFFLOAD
19500 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19501#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019502#ifdef FEATURE_WLAN_SCAN_PNO
19503 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19504 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19505#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019506 .resume = wlan_hdd_cfg80211_resume_wlan,
19507 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019508 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019509#ifdef WLAN_NL80211_TESTMODE
19510 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19511#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019512 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19514 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019515 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019516#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019517};
19518