blob: 529c5b17f6a323ce93412a1d9cce506642d850a1 [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;
Anurag Chouhand64d5232016-08-29 17:01:38 +05303905 int ssid_length;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303906 eHalStatus status;
3907 int i, rem, retval;
3908 unsigned long rc;
3909
3910 ENTER();
3911
3912 if (VOS_FTM_MODE == hdd_get_conparam()) {
3913 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3914 return -EINVAL;
3915 }
3916
3917 retval = wlan_hdd_validate_context(hdd_ctx);
3918 if (0 != retval) {
3919 hddLog(LOGE, FL("HDD context is not valid"));
3920 return -EINVAL;
3921 }
3922
3923 /* check the EXTScan Capability */
3924 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303925 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3926 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303927 {
3928 hddLog(VOS_TRACE_LEVEL_ERROR,
3929 FL("EXTScan not enabled/supported by Firmware"));
3930 return -EINVAL;
3931 }
3932
3933 if (nla_parse(tb, PARAM_MAX,
3934 data, data_len,
3935 wlan_hdd_extscan_config_policy)) {
3936 hddLog(LOGE, FL("Invalid ATTR"));
3937 return -EINVAL;
3938 }
3939
3940 request = vos_mem_malloc(sizeof(*request));
3941 if (!request) {
3942 hddLog(LOGE, FL("vos_mem_malloc failed"));
3943 return -ENOMEM;
3944 }
3945
3946 /* Parse and fetch request Id */
3947 if (!tb[PARAM_REQUEST_ID]) {
3948 hddLog(LOGE, FL("attr request id failed"));
3949 goto fail;
3950 }
3951
3952 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3953 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3954
3955 /* Parse and fetch lost SSID sample size */
3956 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3957 hddLog(LOGE, FL("attr number of Ssid failed"));
3958 goto fail;
3959 }
3960 request->lost_ssid_sample_size =
3961 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3962 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3963 request->lost_ssid_sample_size);
3964
3965 /* Parse and fetch number of hotlist SSID */
3966 if (!tb[PARAMS_NUM_SSID]) {
3967 hddLog(LOGE, FL("attr number of Ssid failed"));
3968 goto fail;
3969 }
3970 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3971 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3972
3973 request->session_id = adapter->sessionId;
3974 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3975
3976 i = 0;
3977 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3978 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3979 hddLog(LOGE,
3980 FL("Too Many SSIDs, %d exceeds %d"),
3981 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3982 break;
3983 }
3984 if (nla_parse(tb2, PARAM_MAX,
3985 nla_data(ssids), nla_len(ssids),
3986 wlan_hdd_extscan_config_policy)) {
3987 hddLog(LOGE, FL("nla_parse failed"));
3988 goto fail;
3989 }
3990
3991 /* Parse and fetch SSID */
3992 if (!tb2[PARAM_SSID]) {
3993 hddLog(LOGE, FL("attr ssid failed"));
3994 goto fail;
3995 }
Anurag Chouhand64d5232016-08-29 17:01:38 +05303996 ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID],
3997 sizeof(ssid_string));
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303998 hddLog(LOG1, FL("SSID %s"),
3999 ssid_string);
4000 ssid_len = strlen(ssid_string);
Anurag Chouhand64d5232016-08-29 17:01:38 +05304001 if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) {
4002 hddLog(LOGE, FL("Invalid ssid length"));
4003 goto fail;
4004 }
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304005 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4006 request->ssid[i].ssid.length = ssid_len;
4007 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4008 hddLog(LOG1, FL("After copying SSID %s"),
4009 request->ssid[i].ssid.ssId);
4010 hddLog(LOG1, FL("After copying length: %d"),
4011 ssid_len);
4012
4013 /* Parse and fetch low RSSI */
4014 if (!tb2[PARAM_BAND]) {
4015 hddLog(LOGE, FL("attr band failed"));
4016 goto fail;
4017 }
4018 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4019 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4020
4021 /* Parse and fetch low RSSI */
4022 if (!tb2[PARAM_RSSI_LOW]) {
4023 hddLog(LOGE, FL("attr low RSSI failed"));
4024 goto fail;
4025 }
4026 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4027 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4028
4029 /* Parse and fetch high RSSI */
4030 if (!tb2[PARAM_RSSI_HIGH]) {
4031 hddLog(LOGE, FL("attr high RSSI failed"));
4032 goto fail;
4033 }
4034 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4035 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4036 i++;
4037 }
4038
4039 context = &hdd_ctx->ext_scan_context;
4040 spin_lock(&hdd_context_lock);
4041 INIT_COMPLETION(context->response_event);
4042 context->request_id = request_id = request->request_id;
4043 spin_unlock(&hdd_context_lock);
4044
4045 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4046 if (!HAL_STATUS_SUCCESS(status)) {
4047 hddLog(LOGE,
4048 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4049 goto fail;
4050 }
4051
4052 vos_mem_free(request);
4053
4054 /* request was sent -- wait for the response */
4055 rc = wait_for_completion_timeout(&context->response_event,
4056 msecs_to_jiffies
4057 (WLAN_WAIT_TIME_EXTSCAN));
4058 if (!rc) {
4059 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4060 retval = -ETIMEDOUT;
4061 } else {
4062 spin_lock(&hdd_context_lock);
4063 if (context->request_id == request_id)
4064 retval = context->response_status;
4065 else
4066 retval = -EINVAL;
4067 spin_unlock(&hdd_context_lock);
4068 }
4069
4070 return retval;
4071
4072fail:
4073 vos_mem_free(request);
4074 return -EINVAL;
4075}
4076
4077/*
4078 * done with short names for the global vendor params
4079 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4080 */
4081#undef PARAM_MAX
4082#undef PARAM_REQUEST_ID
4083#undef PARAMS_NUM_SSID
4084#undef THRESHOLD_PARAM
4085#undef PARAM_SSID
4086#undef PARAM_BAND
4087#undef PARAM_RSSI_LOW
4088#undef PARAM_RSSI_HIGH
4089
4090static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4091 struct wireless_dev *wdev,
4092 const void *data, int dataLen)
4093{
4094 int ret = 0;
4095
4096 vos_ssr_protect(__func__);
4097 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4098 dataLen);
4099 vos_ssr_unprotect(__func__);
4100
4101 return ret;
4102}
4103
4104static int
4105__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4106 struct wireless_dev *wdev,
4107 const void *data,
4108 int data_len)
4109{
4110 tSirEXTScanResetSsidHotlistReqParams request;
4111 struct net_device *dev = wdev->netdev;
4112 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4113 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4114 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4115 struct hdd_ext_scan_context *context;
4116 uint32_t request_id;
4117 eHalStatus status;
4118 int retval;
4119 unsigned long rc;
4120
4121 ENTER();
4122
4123 if (VOS_FTM_MODE == hdd_get_conparam()) {
4124 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4125 return -EINVAL;
4126 }
4127
4128 retval = wlan_hdd_validate_context(hdd_ctx);
4129 if (0 != retval) {
4130 hddLog(LOGE, FL("HDD context is not valid"));
4131 return -EINVAL;
4132 }
4133
4134 /* check the EXTScan Capability */
4135 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304136 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4137 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304138 {
4139 hddLog(LOGE,
4140 FL("EXTScan not enabled/supported by Firmware"));
4141 return -EINVAL;
4142 }
4143
4144 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4145 data, data_len,
4146 wlan_hdd_extscan_config_policy)) {
4147 hddLog(LOGE, FL("Invalid ATTR"));
4148 return -EINVAL;
4149 }
4150
4151 /* Parse and fetch request Id */
4152 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4153 hddLog(LOGE, FL("attr request id failed"));
4154 return -EINVAL;
4155 }
4156
4157 request.requestId = nla_get_u32(
4158 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4159 request.sessionId = adapter->sessionId;
4160 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4161 request.sessionId);
4162
4163 context = &hdd_ctx->ext_scan_context;
4164 spin_lock(&hdd_context_lock);
4165 INIT_COMPLETION(context->response_event);
4166 context->request_id = request_id = request.requestId;
4167 spin_unlock(&hdd_context_lock);
4168
4169 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4170 if (!HAL_STATUS_SUCCESS(status)) {
4171 hddLog(LOGE,
4172 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4173 return -EINVAL;
4174 }
4175
4176 /* request was sent -- wait for the response */
4177 rc = wait_for_completion_timeout(&context->response_event,
4178 msecs_to_jiffies
4179 (WLAN_WAIT_TIME_EXTSCAN));
4180 if (!rc) {
4181 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4182 retval = -ETIMEDOUT;
4183 } else {
4184 spin_lock(&hdd_context_lock);
4185 if (context->request_id == request_id)
4186 retval = context->response_status;
4187 else
4188 retval = -EINVAL;
4189 spin_unlock(&hdd_context_lock);
4190 }
4191
4192 return retval;
4193}
4194
4195static int
4196wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4197 struct wireless_dev *wdev,
4198 const void *data,
4199 int data_len)
4200{
4201 int ret;
4202
4203 vos_ssr_protect(__func__);
4204 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4205 data, data_len);
4206 vos_ssr_unprotect(__func__);
4207
4208 return ret;
4209}
4210
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304211static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304212 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304213 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304215 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4216 struct net_device *dev = wdev->netdev;
4217 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4218 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4219 uint8_t num_channels = 0;
4220 uint8_t num_chan_new = 0;
4221 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304222 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304223 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304224 tWifiBand wifiBand;
4225 eHalStatus status;
4226 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304227 tANI_U8 i,j,k;
4228 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304230 ENTER();
4231
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 status = wlan_hdd_validate_context(pHddCtx);
4233 if (0 != status)
4234 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304235 return -EINVAL;
4236 }
Dino Myclee8843b32014-07-04 14:21:45 +05304237
Dino Mycle6fb96c12014-06-10 11:52:40 +05304238 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4239 data, dataLen,
4240 wlan_hdd_extscan_config_policy)) {
4241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4242 return -EINVAL;
4243 }
4244
4245 /* Parse and fetch request Id */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4248 return -EINVAL;
4249 }
4250 requestId = nla_get_u32(
4251 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4252 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4253
4254 /* Parse and fetch wifi band */
4255 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4256 {
4257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4258 return -EINVAL;
4259 }
4260 wifiBand = nla_get_u32(
4261 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4263
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304264 /* Parse and fetch max channels */
4265 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4266 {
4267 hddLog(LOGE, FL("attr max channels failed"));
4268 return -EINVAL;
4269 }
4270 maxChannels = nla_get_u32(
4271 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4272 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4273
Dino Mycle6fb96c12014-06-10 11:52:40 +05304274 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304275 wifiBand, chan_list,
4276 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304277 if (eHAL_STATUS_SUCCESS != status) {
4278 hddLog(VOS_TRACE_LEVEL_ERROR,
4279 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4280 return -EINVAL;
4281 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304282
Agrawal Ashish16abf782016-08-18 22:42:59 +05304283 num_channels = VOS_MIN(num_channels, maxChannels);
4284 num_chan_new = num_channels;
4285 /* remove the indoor only channels if iface is SAP */
4286 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4287 {
4288 num_chan_new = 0;
4289 for (i = 0; i < num_channels; i++)
4290 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4291 if (wiphy->bands[j] == NULL)
4292 continue;
4293 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4294 if ((chan_list[i] ==
4295 wiphy->bands[j]->channels[k].center_freq) &&
4296 (!(wiphy->bands[j]->channels[k].flags &
4297 IEEE80211_CHAN_INDOOR_ONLY))) {
4298 chan_list[num_chan_new] = chan_list[i];
4299 num_chan_new++;
4300 }
4301 }
4302 }
4303 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304304
Agrawal Ashish16abf782016-08-18 22:42:59 +05304305 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4306 for (i = 0; i < num_chan_new; i++)
4307 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4308 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309
4310 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304311 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304312 NLMSG_HDRLEN);
4313
4314 if (!replySkb) {
4315 hddLog(VOS_TRACE_LEVEL_ERROR,
4316 FL("valid channels: buffer alloc fail"));
4317 return -EINVAL;
4318 }
4319 if (nla_put_u32(replySkb,
4320 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304321 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304322 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304323 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304324
4325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4326 kfree_skb(replySkb);
4327 return -EINVAL;
4328 }
4329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304330 ret = cfg80211_vendor_cmd_reply(replySkb);
4331
4332 EXIT();
4333 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304334}
4335
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304336static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4337 struct wireless_dev *wdev,
4338 const void *data, int dataLen)
4339{
4340 int ret = 0;
4341
4342 vos_ssr_protect(__func__);
4343 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4344 dataLen);
4345 vos_ssr_unprotect(__func__);
4346
4347 return ret;
4348}
4349
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304350static int hdd_extscan_start_fill_bucket_channel_spec(
4351 hdd_context_t *pHddCtx,
4352 tpSirEXTScanStartReqParams pReqMsg,
4353 struct nlattr **tb)
4354{
4355 struct nlattr *bucket[
4356 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4357 struct nlattr *channel[
4358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4359 struct nlattr *buckets;
4360 struct nlattr *channels;
4361 int rem1, rem2;
4362 eHalStatus status;
4363 tANI_U8 bktIndex, j, numChannels;
4364 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4365 tANI_U32 passive_max_chn_time, active_max_chn_time;
4366
4367 bktIndex = 0;
4368
4369 nla_for_each_nested(buckets,
4370 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4371 if (nla_parse(bucket,
4372 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4373 nla_data(buckets), nla_len(buckets), NULL)) {
4374 hddLog(LOGE, FL("nla_parse failed"));
4375 return -EINVAL;
4376 }
4377
4378 /* Parse and fetch bucket spec */
4379 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4380 hddLog(LOGE, FL("attr bucket index failed"));
4381 return -EINVAL;
4382 }
4383 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4384 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4385 hddLog(LOG1, FL("Bucket spec Index %d"),
4386 pReqMsg->buckets[bktIndex].bucket);
4387
4388 /* Parse and fetch wifi band */
4389 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4390 hddLog(LOGE, FL("attr wifi band failed"));
4391 return -EINVAL;
4392 }
4393 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4394 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4395 hddLog(LOG1, FL("Wifi band %d"),
4396 pReqMsg->buckets[bktIndex].band);
4397
4398 /* Parse and fetch period */
4399 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4400 hddLog(LOGE, FL("attr period failed"));
4401 return -EINVAL;
4402 }
4403 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4404 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4405 hddLog(LOG1, FL("period %d"),
4406 pReqMsg->buckets[bktIndex].period);
4407
4408 /* Parse and fetch report events */
4409 if (!bucket[
4410 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4411 hddLog(LOGE, FL("attr report events failed"));
4412 return -EINVAL;
4413 }
4414 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4415 bucket[
4416 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4417 hddLog(LOG1, FL("report events %d"),
4418 pReqMsg->buckets[bktIndex].reportEvents);
4419
4420 /* Parse and fetch max period */
4421 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4422 hddLog(LOGE, FL("attr max period failed"));
4423 return -EINVAL;
4424 }
4425 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4426 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4427 hddLog(LOG1, FL("max period %u"),
4428 pReqMsg->buckets[bktIndex].max_period);
4429
4430 /* Parse and fetch exponent */
4431 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4432 hddLog(LOGE, FL("attr exponent failed"));
4433 return -EINVAL;
4434 }
4435 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4436 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4437 hddLog(LOG1, FL("exponent %u"),
4438 pReqMsg->buckets[bktIndex].exponent);
4439
4440 /* Parse and fetch step count */
4441 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4442 hddLog(LOGE, FL("attr step count failed"));
4443 return -EINVAL;
4444 }
4445 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4446 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4447 hddLog(LOG1, FL("Step count %u"),
4448 pReqMsg->buckets[bktIndex].step_count);
4449
4450 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4451 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4452
4453 /* Framework shall pass the channel list if the input WiFi band is
4454 * WIFI_BAND_UNSPECIFIED.
4455 * If the input WiFi band is specified (any value other than
4456 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4457 */
4458 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4459 numChannels = 0;
4460 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4461 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4462 pReqMsg->buckets[bktIndex].band,
4463 chanList, &numChannels);
4464 if (!HAL_STATUS_SUCCESS(status)) {
4465 hddLog(LOGE,
4466 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4467 status);
4468 return -EINVAL;
4469 }
4470
4471 pReqMsg->buckets[bktIndex].numChannels =
4472 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4473 hddLog(LOG1, FL("Num channels %d"),
4474 pReqMsg->buckets[bktIndex].numChannels);
4475
4476 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4477 j++) {
4478 pReqMsg->buckets[bktIndex].channels[j].channel =
4479 chanList[j];
4480 pReqMsg->buckets[bktIndex].channels[j].
4481 chnlClass = 0;
4482 if (CSR_IS_CHANNEL_DFS(
4483 vos_freq_to_chan(chanList[j]))) {
4484 pReqMsg->buckets[bktIndex].channels[j].
4485 passive = 1;
4486 pReqMsg->buckets[bktIndex].channels[j].
4487 dwellTimeMs = passive_max_chn_time;
4488 } else {
4489 pReqMsg->buckets[bktIndex].channels[j].
4490 passive = 0;
4491 pReqMsg->buckets[bktIndex].channels[j].
4492 dwellTimeMs = active_max_chn_time;
4493 }
4494
4495 hddLog(LOG1,
4496 "Channel %u Passive %u Dwell time %u ms",
4497 pReqMsg->buckets[bktIndex].channels[j].channel,
4498 pReqMsg->buckets[bktIndex].channels[j].passive,
4499 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4500 }
4501
4502 bktIndex++;
4503 continue;
4504 }
4505
4506 /* Parse and fetch number of channels */
4507 if (!bucket[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4509 hddLog(LOGE, FL("attr num channels failed"));
4510 return -EINVAL;
4511 }
4512
4513 pReqMsg->buckets[bktIndex].numChannels =
4514 nla_get_u32(bucket[
4515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4516 hddLog(LOG1, FL("num channels %d"),
4517 pReqMsg->buckets[bktIndex].numChannels);
4518
4519 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4520 hddLog(LOGE, FL("attr channel spec failed"));
4521 return -EINVAL;
4522 }
4523
4524 j = 0;
4525 nla_for_each_nested(channels,
4526 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4527 if (nla_parse(channel,
4528 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4529 nla_data(channels), nla_len(channels),
4530 wlan_hdd_extscan_config_policy)) {
4531 hddLog(LOGE, FL("nla_parse failed"));
4532 return -EINVAL;
4533 }
4534
4535 /* Parse and fetch channel */
4536 if (!channel[
4537 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4538 hddLog(LOGE, FL("attr channel failed"));
4539 return -EINVAL;
4540 }
4541 pReqMsg->buckets[bktIndex].channels[j].channel =
4542 nla_get_u32(channel[
4543 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4544 hddLog(LOG1, FL("channel %u"),
4545 pReqMsg->buckets[bktIndex].channels[j].channel);
4546
4547 /* Parse and fetch dwell time */
4548 if (!channel[
4549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4550 hddLog(LOGE, FL("attr dwelltime failed"));
4551 return -EINVAL;
4552 }
4553 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4554 nla_get_u32(channel[
4555 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4556
4557 hddLog(LOG1, FL("Dwell time (%u ms)"),
4558 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4559
4560
4561 /* Parse and fetch channel spec passive */
4562 if (!channel[
4563 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4564 hddLog(LOGE,
4565 FL("attr channel spec passive failed"));
4566 return -EINVAL;
4567 }
4568 pReqMsg->buckets[bktIndex].channels[j].passive =
4569 nla_get_u8(channel[
4570 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4571 hddLog(LOG1, FL("Chnl spec passive %u"),
4572 pReqMsg->buckets[bktIndex].channels[j].passive);
4573
4574 j++;
4575 }
4576
4577 bktIndex++;
4578 }
4579
4580 return 0;
4581}
4582
4583
4584/*
4585 * define short names for the global vendor params
4586 * used by wlan_hdd_cfg80211_extscan_start()
4587 */
4588#define PARAM_MAX \
4589QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4590#define PARAM_REQUEST_ID \
4591QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4592#define PARAM_BASE_PERIOD \
4593QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4594#define PARAM_MAX_AP_PER_SCAN \
4595QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4596#define PARAM_RPT_THRHLD_PERCENT \
4597QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4598#define PARAM_RPT_THRHLD_NUM_SCANS \
4599QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4600#define PARAM_NUM_BUCKETS \
4601QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4602
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304603static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304604 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304605 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606{
Dino Myclee8843b32014-07-04 14:21:45 +05304607 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304608 struct net_device *dev = wdev->netdev;
4609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4610 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4611 struct nlattr *tb[PARAM_MAX + 1];
4612 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304614 tANI_U32 request_id;
4615 struct hdd_ext_scan_context *context;
4616 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304618 ENTER();
4619
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304620 if (VOS_FTM_MODE == hdd_get_conparam()) {
4621 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4622 return -EINVAL;
4623 }
4624
Dino Mycle6fb96c12014-06-10 11:52:40 +05304625 status = wlan_hdd_validate_context(pHddCtx);
4626 if (0 != status)
4627 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 return -EINVAL;
4629 }
Dino Myclee8843b32014-07-04 14:21:45 +05304630 /* check the EXTScan Capability */
4631 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304632 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4633 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304634 {
4635 hddLog(VOS_TRACE_LEVEL_ERROR,
4636 FL("EXTScan not enabled/supported by Firmware"));
4637 return -EINVAL;
4638 }
4639
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304640 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304641 data, dataLen,
4642 wlan_hdd_extscan_config_policy)) {
4643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4644 return -EINVAL;
4645 }
4646
4647 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304648 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4650 return -EINVAL;
4651 }
4652
Dino Myclee8843b32014-07-04 14:21:45 +05304653 pReqMsg = (tpSirEXTScanStartReqParams)
4654 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4657 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 }
4659
4660 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304661 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4663
4664 pReqMsg->sessionId = pAdapter->sessionId;
4665 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4666
4667 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304668 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4670 goto fail;
4671 }
4672 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304673 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304674 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4675 pReqMsg->basePeriod);
4676
4677 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304678 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4680 goto fail;
4681 }
4682 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304683 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304684 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4685 pReqMsg->maxAPperScan);
4686
4687 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304688 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4690 goto fail;
4691 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304692 pReqMsg->reportThresholdPercent = nla_get_u8(
4693 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304695 pReqMsg->reportThresholdPercent);
4696
4697 /* Parse and fetch report threshold num scans */
4698 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4699 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4700 goto fail;
4701 }
4702 pReqMsg->reportThresholdNumScans = nla_get_u8(
4703 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4704 hddLog(LOG1, FL("Report Threshold num scans %d"),
4705 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304706
4707 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304708 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4710 goto fail;
4711 }
4712 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4715 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4716 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4717 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4718 }
4719 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4720 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304721
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4724 goto fail;
4725 }
4726
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304727 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304728
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304729 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4730 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304731
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304732 context = &pHddCtx->ext_scan_context;
4733 spin_lock(&hdd_context_lock);
4734 INIT_COMPLETION(context->response_event);
4735 context->request_id = request_id = pReqMsg->requestId;
4736 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304737
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4739 if (!HAL_STATUS_SUCCESS(status)) {
4740 hddLog(VOS_TRACE_LEVEL_ERROR,
4741 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304742 goto fail;
4743 }
4744
Srinivas Dasari91727c12016-03-23 17:59:06 +05304745 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
4746
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304747 /* request was sent -- wait for the response */
4748 rc = wait_for_completion_timeout(&context->response_event,
4749 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4750
4751 if (!rc) {
4752 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4753 retval = -ETIMEDOUT;
4754 } else {
4755 spin_lock(&hdd_context_lock);
4756 if (context->request_id == request_id)
4757 retval = context->response_status;
4758 else
4759 retval = -EINVAL;
4760 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304761 }
4762
Dino Myclee8843b32014-07-04 14:21:45 +05304763 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304764 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304765 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304766
4767fail:
4768 vos_mem_free(pReqMsg);
4769 return -EINVAL;
4770}
4771
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304772/*
4773 * done with short names for the global vendor params
4774 * used by wlan_hdd_cfg80211_extscan_start()
4775 */
4776#undef PARAM_MAX
4777#undef PARAM_REQUEST_ID
4778#undef PARAM_BASE_PERIOD
4779#undef PARAMS_MAX_AP_PER_SCAN
4780#undef PARAMS_RPT_THRHLD_PERCENT
4781#undef PARAMS_RPT_THRHLD_NUM_SCANS
4782#undef PARAMS_NUM_BUCKETS
4783
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304784static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4785 struct wireless_dev *wdev,
4786 const void *data, int dataLen)
4787{
4788 int ret = 0;
4789
4790 vos_ssr_protect(__func__);
4791 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4792 vos_ssr_unprotect(__func__);
4793
4794 return ret;
4795}
4796
4797static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304798 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304799 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304800{
Dino Myclee8843b32014-07-04 14:21:45 +05304801 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 struct net_device *dev = wdev->netdev;
4803 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4804 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4805 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4806 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304807 int retval;
4808 unsigned long rc;
4809 struct hdd_ext_scan_context *context;
4810 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304812 ENTER();
4813
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304814 if (VOS_FTM_MODE == hdd_get_conparam()) {
4815 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4816 return -EINVAL;
4817 }
4818
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819 status = wlan_hdd_validate_context(pHddCtx);
4820 if (0 != status)
4821 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 return -EINVAL;
4823 }
Dino Myclee8843b32014-07-04 14:21:45 +05304824 /* check the EXTScan Capability */
4825 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304826 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4827 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304828 {
4829 hddLog(VOS_TRACE_LEVEL_ERROR,
4830 FL("EXTScan not enabled/supported by Firmware"));
4831 return -EINVAL;
4832 }
4833
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4835 data, dataLen,
4836 wlan_hdd_extscan_config_policy)) {
4837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4838 return -EINVAL;
4839 }
4840
4841 /* Parse and fetch request Id */
4842 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4844 return -EINVAL;
4845 }
4846
Dino Myclee8843b32014-07-04 14:21:45 +05304847 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304849 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304850
Dino Myclee8843b32014-07-04 14:21:45 +05304851 reqMsg.sessionId = pAdapter->sessionId;
4852 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304854 context = &pHddCtx->ext_scan_context;
4855 spin_lock(&hdd_context_lock);
4856 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05304857 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304858 spin_unlock(&hdd_context_lock);
4859
Dino Myclee8843b32014-07-04 14:21:45 +05304860 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304861 if (!HAL_STATUS_SUCCESS(status)) {
4862 hddLog(VOS_TRACE_LEVEL_ERROR,
4863 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304864 return -EINVAL;
4865 }
4866
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304867 /* request was sent -- wait for the response */
4868 rc = wait_for_completion_timeout(&context->response_event,
4869 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4870
4871 if (!rc) {
4872 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4873 retval = -ETIMEDOUT;
4874 } else {
4875 spin_lock(&hdd_context_lock);
4876 if (context->request_id == request_id)
4877 retval = context->response_status;
4878 else
4879 retval = -EINVAL;
4880 spin_unlock(&hdd_context_lock);
4881 }
4882
4883 return retval;
4884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304885 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304886 return 0;
4887}
4888
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304889static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4890 struct wireless_dev *wdev,
4891 const void *data, int dataLen)
4892{
4893 int ret = 0;
4894
4895 vos_ssr_protect(__func__);
4896 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4897 vos_ssr_unprotect(__func__);
4898
4899 return ret;
4900}
4901
4902static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304903 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304904 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304905{
Dino Myclee8843b32014-07-04 14:21:45 +05304906 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304907 struct net_device *dev = wdev->netdev;
4908 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4909 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4910 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4911 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304912 struct hdd_ext_scan_context *context;
4913 tANI_U32 request_id;
4914 unsigned long rc;
4915 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304916
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304917 ENTER();
4918
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304919 if (VOS_FTM_MODE == hdd_get_conparam()) {
4920 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4921 return -EINVAL;
4922 }
4923
Dino Mycle6fb96c12014-06-10 11:52:40 +05304924 status = wlan_hdd_validate_context(pHddCtx);
4925 if (0 != status)
4926 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304927 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304928 return -EINVAL;
4929 }
Dino Myclee8843b32014-07-04 14:21:45 +05304930 /* check the EXTScan Capability */
4931 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304932 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4933 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304934 {
4935 hddLog(VOS_TRACE_LEVEL_ERROR,
4936 FL("EXTScan not enabled/supported by Firmware"));
4937 return -EINVAL;
4938 }
4939
Dino Mycle6fb96c12014-06-10 11:52:40 +05304940 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4941 data, dataLen,
4942 wlan_hdd_extscan_config_policy)) {
4943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4944 return -EINVAL;
4945 }
4946
4947 /* Parse and fetch request Id */
4948 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4950 return -EINVAL;
4951 }
4952
Dino Myclee8843b32014-07-04 14:21:45 +05304953 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304954 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304955 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304956
Dino Myclee8843b32014-07-04 14:21:45 +05304957 reqMsg.sessionId = pAdapter->sessionId;
4958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304959
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304960 context = &pHddCtx->ext_scan_context;
4961 spin_lock(&hdd_context_lock);
4962 INIT_COMPLETION(context->response_event);
4963 context->request_id = request_id = reqMsg.requestId;
4964 spin_unlock(&hdd_context_lock);
4965
Dino Myclee8843b32014-07-04 14:21:45 +05304966 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304967 if (!HAL_STATUS_SUCCESS(status)) {
4968 hddLog(VOS_TRACE_LEVEL_ERROR,
4969 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304970 return -EINVAL;
4971 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304972
4973 /* request was sent -- wait for the response */
4974 rc = wait_for_completion_timeout(&context->response_event,
4975 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4976 if (!rc) {
4977 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4978 retval = -ETIMEDOUT;
4979 } else {
4980 spin_lock(&hdd_context_lock);
4981 if (context->request_id == request_id)
4982 retval = context->response_status;
4983 else
4984 retval = -EINVAL;
4985 spin_unlock(&hdd_context_lock);
4986 }
4987
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304988 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304989 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304990}
4991
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304992static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4993 struct wireless_dev *wdev,
4994 const void *data, int dataLen)
4995{
4996 int ret = 0;
4997
4998 vos_ssr_protect(__func__);
4999 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5000 vos_ssr_unprotect(__func__);
5001
5002 return ret;
5003}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305004#endif /* WLAN_FEATURE_EXTSCAN */
5005
Atul Mittal115287b2014-07-08 13:26:33 +05305006/*EXT TDLS*/
5007static const struct nla_policy
5008wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5009{
5010 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5011 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5012 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5013 {.type = NLA_S32 },
5014 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5016
5017};
5018
5019static const struct nla_policy
5020wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5021{
5022 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5023
5024};
5025
5026static const struct nla_policy
5027wlan_hdd_tdls_config_state_change_policy[
5028 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5029{
5030 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5031 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5032 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305033 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5034 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5035 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305036
5037};
5038
5039static const struct nla_policy
5040wlan_hdd_tdls_config_get_status_policy[
5041 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5042{
5043 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5044 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5045 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305046 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5047 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5048 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305049
5050};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051
5052static const struct nla_policy
5053wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5054{
5055 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5056};
5057
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305058static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305059 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305060 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305061 int data_len)
5062{
5063
5064 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5065 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305067 ENTER();
5068
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305069 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305070 return -EINVAL;
5071 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305072 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305073 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305074 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305075 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305076 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305077 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305078 return -ENOTSUPP;
5079 }
5080
5081 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5082 data, data_len, wlan_hdd_mac_config)) {
5083 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5084 return -EINVAL;
5085 }
5086
5087 /* Parse and fetch mac address */
5088 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5090 return -EINVAL;
5091 }
5092
5093 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5094 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5095 VOS_MAC_ADDR_LAST_3_BYTES);
5096
Siddharth Bhal76972212014-10-15 16:22:51 +05305097 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5098
5099 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305100 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5101 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305102 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5103 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5104 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5105 {
5106 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5107 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5108 VOS_MAC_ADDRESS_LEN);
5109 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305110 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305111
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305112 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5113 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305114
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305115 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305116 return 0;
5117}
5118
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305119static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5120 struct wireless_dev *wdev,
5121 const void *data,
5122 int data_len)
5123{
5124 int ret = 0;
5125
5126 vos_ssr_protect(__func__);
5127 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5128 vos_ssr_unprotect(__func__);
5129
5130 return ret;
5131}
5132
5133static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305134 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305135 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305136 int data_len)
5137{
5138 u8 peer[6] = {0};
5139 struct net_device *dev = wdev->netdev;
5140 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5141 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5142 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5143 eHalStatus ret;
5144 tANI_S32 state;
5145 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305146 tANI_S32 global_operating_class = 0;
5147 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305148 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305149 int retVal;
5150
5151 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305152
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305153 if (!pAdapter) {
5154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5155 return -EINVAL;
5156 }
5157
Atul Mittal115287b2014-07-08 13:26:33 +05305158 ret = wlan_hdd_validate_context(pHddCtx);
5159 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305161 return -EINVAL;
5162 }
5163 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305165 return -ENOTSUPP;
5166 }
5167 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5168 data, data_len,
5169 wlan_hdd_tdls_config_get_status_policy)) {
5170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5171 return -EINVAL;
5172 }
5173
5174 /* Parse and fetch mac address */
5175 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5177 return -EINVAL;
5178 }
5179
5180 memcpy(peer, nla_data(
5181 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5182 sizeof(peer));
5183 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5184
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305185 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305186
Atul Mittal115287b2014-07-08 13:26:33 +05305187 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305188 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305189 NLMSG_HDRLEN);
5190
5191 if (!skb) {
5192 hddLog(VOS_TRACE_LEVEL_ERROR,
5193 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5194 return -EINVAL;
5195 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 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 +05305197 reason,
5198 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305199 global_operating_class,
5200 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305201 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305202 if (nla_put_s32(skb,
5203 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5204 state) ||
5205 nla_put_s32(skb,
5206 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5207 reason) ||
5208 nla_put_s32(skb,
5209 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5210 global_operating_class) ||
5211 nla_put_s32(skb,
5212 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5213 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305214
5215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5216 goto nla_put_failure;
5217 }
5218
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305219 retVal = cfg80211_vendor_cmd_reply(skb);
5220 EXIT();
5221 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305222
5223nla_put_failure:
5224 kfree_skb(skb);
5225 return -EINVAL;
5226}
5227
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305228static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5229 struct wireless_dev *wdev,
5230 const void *data,
5231 int data_len)
5232{
5233 int ret = 0;
5234
5235 vos_ssr_protect(__func__);
5236 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5237 vos_ssr_unprotect(__func__);
5238
5239 return ret;
5240}
5241
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305242static int wlan_hdd_cfg80211_exttdls_callback(
5243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5244 const tANI_U8* mac,
5245#else
5246 tANI_U8* mac,
5247#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305248 tANI_S32 state,
5249 tANI_S32 reason,
5250 void *ctx)
5251{
5252 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305253 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305254 tANI_S32 global_operating_class = 0;
5255 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305256 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305258 ENTER();
5259
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305260 if (!pAdapter) {
5261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5262 return -EINVAL;
5263 }
5264
5265 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305266 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305268 return -EINVAL;
5269 }
5270
5271 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305273 return -ENOTSUPP;
5274 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305275 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5277 NULL,
5278#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305279 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5280 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5281 GFP_KERNEL);
5282
5283 if (!skb) {
5284 hddLog(VOS_TRACE_LEVEL_ERROR,
5285 FL("cfg80211_vendor_event_alloc failed"));
5286 return -EINVAL;
5287 }
5288 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305289 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5290 reason,
5291 state,
5292 global_operating_class,
5293 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305294 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5295 MAC_ADDR_ARRAY(mac));
5296
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305297 if (nla_put(skb,
5298 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5299 VOS_MAC_ADDR_SIZE, mac) ||
5300 nla_put_s32(skb,
5301 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5302 state) ||
5303 nla_put_s32(skb,
5304 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5305 reason) ||
5306 nla_put_s32(skb,
5307 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5308 channel) ||
5309 nla_put_s32(skb,
5310 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5311 global_operating_class)
5312 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5314 goto nla_put_failure;
5315 }
5316
5317 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305318 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305319 return (0);
5320
5321nla_put_failure:
5322 kfree_skb(skb);
5323 return -EINVAL;
5324}
5325
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305326static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305327 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305328 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305329 int data_len)
5330{
5331 u8 peer[6] = {0};
5332 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305333 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5334 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5335 eHalStatus status;
5336 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305337 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305338 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305339
5340 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305341
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305342 if (!dev) {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5344 return -EINVAL;
5345 }
5346
5347 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5348 if (!pAdapter) {
5349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5350 return -EINVAL;
5351 }
5352
Atul Mittal115287b2014-07-08 13:26:33 +05305353 status = wlan_hdd_validate_context(pHddCtx);
5354 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305356 return -EINVAL;
5357 }
5358 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305360 return -ENOTSUPP;
5361 }
5362 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5363 data, data_len,
5364 wlan_hdd_tdls_config_enable_policy)) {
5365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5366 return -EINVAL;
5367 }
5368
5369 /* Parse and fetch mac address */
5370 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5372 return -EINVAL;
5373 }
5374
5375 memcpy(peer, nla_data(
5376 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5377 sizeof(peer));
5378 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5379
5380 /* Parse and fetch channel */
5381 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5383 return -EINVAL;
5384 }
5385 pReqMsg.channel = nla_get_s32(
5386 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5387 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5388
5389 /* Parse and fetch global operating class */
5390 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5391 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5392 return -EINVAL;
5393 }
5394 pReqMsg.global_operating_class = nla_get_s32(
5395 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5396 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5397 pReqMsg.global_operating_class);
5398
5399 /* Parse and fetch latency ms */
5400 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5402 return -EINVAL;
5403 }
5404 pReqMsg.max_latency_ms = nla_get_s32(
5405 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5407 pReqMsg.max_latency_ms);
5408
5409 /* Parse and fetch required bandwidth kbps */
5410 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5412 return -EINVAL;
5413 }
5414
5415 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5416 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5417 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5418 pReqMsg.min_bandwidth_kbps);
5419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305420 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305421 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305422 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305423 wlan_hdd_cfg80211_exttdls_callback);
5424
5425 EXIT();
5426 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305427}
5428
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305429static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5430 struct wireless_dev *wdev,
5431 const void *data,
5432 int data_len)
5433{
5434 int ret = 0;
5435
5436 vos_ssr_protect(__func__);
5437 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5438 vos_ssr_unprotect(__func__);
5439
5440 return ret;
5441}
5442
5443static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305444 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305445 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305446 int data_len)
5447{
5448 u8 peer[6] = {0};
5449 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305450 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5451 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5452 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305453 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305454 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305455
5456 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305457
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305458 if (!dev) {
5459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5460 return -EINVAL;
5461 }
5462
5463 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5464 if (!pAdapter) {
5465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5466 return -EINVAL;
5467 }
5468
Atul Mittal115287b2014-07-08 13:26:33 +05305469 status = wlan_hdd_validate_context(pHddCtx);
5470 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305472 return -EINVAL;
5473 }
5474 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305476 return -ENOTSUPP;
5477 }
5478 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5479 data, data_len,
5480 wlan_hdd_tdls_config_disable_policy)) {
5481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5482 return -EINVAL;
5483 }
5484 /* Parse and fetch mac address */
5485 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5487 return -EINVAL;
5488 }
5489
5490 memcpy(peer, nla_data(
5491 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5492 sizeof(peer));
5493 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305495 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5496
5497 EXIT();
5498 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305499}
5500
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305501static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5502 struct wireless_dev *wdev,
5503 const void *data,
5504 int data_len)
5505{
5506 int ret = 0;
5507
5508 vos_ssr_protect(__func__);
5509 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5510 vos_ssr_unprotect(__func__);
5511
5512 return ret;
5513}
5514
Dasari Srinivas7875a302014-09-26 17:50:57 +05305515static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305516__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305517 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305518 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305519{
5520 struct net_device *dev = wdev->netdev;
5521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5522 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5523 struct sk_buff *skb = NULL;
5524 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305525 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305526
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305527 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305528
5529 ret = wlan_hdd_validate_context(pHddCtx);
5530 if (0 != ret)
5531 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305532 return ret;
5533 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305534 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5535 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5536 fset |= WIFI_FEATURE_INFRA;
5537 }
5538
5539 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5540 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5541 fset |= WIFI_FEATURE_INFRA_5G;
5542 }
5543
5544#ifdef WLAN_FEATURE_P2P
5545 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5546 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5547 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5548 fset |= WIFI_FEATURE_P2P;
5549 }
5550#endif
5551
5552 /* Soft-AP is supported currently by default */
5553 fset |= WIFI_FEATURE_SOFT_AP;
5554
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305555 /* HOTSPOT is a supplicant feature, enable it by default */
5556 fset |= WIFI_FEATURE_HOTSPOT;
5557
Dasari Srinivas7875a302014-09-26 17:50:57 +05305558#ifdef WLAN_FEATURE_EXTSCAN
5559 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305560 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5561 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5562 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305563 fset |= WIFI_FEATURE_EXTSCAN;
5564 }
5565#endif
5566
Dasari Srinivas7875a302014-09-26 17:50:57 +05305567 if (sme_IsFeatureSupportedByFW(NAN)) {
5568 hddLog(LOG1, FL("NAN is supported by firmware"));
5569 fset |= WIFI_FEATURE_NAN;
5570 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305571
5572 /* D2D RTT is not supported currently by default */
5573 if (sme_IsFeatureSupportedByFW(RTT)) {
5574 hddLog(LOG1, FL("RTT is supported by firmware"));
5575 fset |= WIFI_FEATURE_D2AP_RTT;
5576 }
5577
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305578 if (sme_IsFeatureSupportedByFW(RTT3)) {
5579 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5580 fset |= WIFI_FEATURE_RTT3;
5581 }
5582
Dasari Srinivas7875a302014-09-26 17:50:57 +05305583#ifdef FEATURE_WLAN_BATCH_SCAN
5584 if (fset & WIFI_FEATURE_EXTSCAN) {
5585 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5586 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5587 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5588 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5589 fset |= WIFI_FEATURE_BATCH_SCAN;
5590 }
5591#endif
5592
5593#ifdef FEATURE_WLAN_SCAN_PNO
5594 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5595 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5596 hddLog(LOG1, FL("PNO is supported by firmware"));
5597 fset |= WIFI_FEATURE_PNO;
5598 }
5599#endif
5600
5601 /* STA+STA is supported currently by default */
5602 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5603
5604#ifdef FEATURE_WLAN_TDLS
5605 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5606 sme_IsFeatureSupportedByFW(TDLS)) {
5607 hddLog(LOG1, FL("TDLS is supported by firmware"));
5608 fset |= WIFI_FEATURE_TDLS;
5609 }
5610
5611 /* TDLS_OFFCHANNEL is not supported currently by default */
5612#endif
5613
5614#ifdef WLAN_AP_STA_CONCURRENCY
5615 /* AP+STA concurrency is supported currently by default */
5616 fset |= WIFI_FEATURE_AP_STA;
5617#endif
5618
Mukul Sharma5add0532015-08-17 15:57:47 +05305619#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5620 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5621 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5622#endif
5623
Dasari Srinivas7875a302014-09-26 17:50:57 +05305624 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5625 NLMSG_HDRLEN);
5626
5627 if (!skb) {
5628 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5629 return -EINVAL;
5630 }
5631 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5632
5633 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5634 hddLog(LOGE, FL("nla put fail"));
5635 goto nla_put_failure;
5636 }
5637
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305638 ret = cfg80211_vendor_cmd_reply(skb);
5639 EXIT();
5640 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305641
5642nla_put_failure:
5643 kfree_skb(skb);
5644 return -EINVAL;
5645}
5646
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305647static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305648wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5649 struct wireless_dev *wdev,
5650 const void *data, int data_len)
5651{
5652 int ret = 0;
5653
5654 vos_ssr_protect(__func__);
5655 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5656 vos_ssr_unprotect(__func__);
5657
5658 return ret;
5659}
5660
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305661
5662static const struct
5663nla_policy
5664qca_wlan_vendor_wifi_logger_get_ring_data_policy
5665[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5666 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5667 = {.type = NLA_U32 },
5668};
5669
5670static int
5671 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5672 struct wireless_dev *wdev,
5673 const void *data,
5674 int data_len)
5675{
5676 int ret;
5677 VOS_STATUS status;
5678 uint32_t ring_id;
5679 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5680 struct nlattr *tb
5681 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5682
5683 ENTER();
5684
5685 ret = wlan_hdd_validate_context(hdd_ctx);
5686 if (0 != ret) {
5687 return ret;
5688 }
5689
5690 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5691 data, data_len,
5692 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5693 hddLog(LOGE, FL("Invalid attribute"));
5694 return -EINVAL;
5695 }
5696
5697 /* Parse and fetch ring id */
5698 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5699 hddLog(LOGE, FL("attr ATTR failed"));
5700 return -EINVAL;
5701 }
5702
5703 ring_id = nla_get_u32(
5704 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5705
5706 hddLog(LOG1, FL("Bug report triggered by framework"));
5707
5708 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5709 WLAN_LOG_INDICATOR_FRAMEWORK,
5710 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305711 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305712 );
5713 if (VOS_STATUS_SUCCESS != status) {
5714 hddLog(LOGE, FL("Failed to trigger bug report"));
5715
5716 return -EINVAL;
5717 }
5718
5719 return 0;
5720
5721
5722}
5723
5724
5725static int
5726 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5727 struct wireless_dev *wdev,
5728 const void *data,
5729 int data_len)
5730{
5731 int ret = 0;
5732
5733 vos_ssr_protect(__func__);
5734 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5735 wdev, data, data_len);
5736 vos_ssr_unprotect(__func__);
5737
5738 return ret;
5739
5740}
5741
5742
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305743static int
5744__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305745 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305746 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305747{
5748 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5749 uint8_t i, feature_sets, max_feature_sets;
5750 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5751 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305752 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5753 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305754
5755 ENTER();
5756
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305757 ret = wlan_hdd_validate_context(pHddCtx);
5758 if (0 != ret)
5759 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305760 return ret;
5761 }
5762
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305763 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5764 data, data_len, NULL)) {
5765 hddLog(LOGE, FL("Invalid ATTR"));
5766 return -EINVAL;
5767 }
5768
5769 /* Parse and fetch max feature set */
5770 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5771 hddLog(LOGE, FL("Attr max feature set size failed"));
5772 return -EINVAL;
5773 }
5774 max_feature_sets = nla_get_u32(
5775 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5776 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5777
5778 /* Fill feature combination matrix */
5779 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305780 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5781 WIFI_FEATURE_P2P;
5782
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305783 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5784 WIFI_FEATURE_SOFT_AP;
5785
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305786 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5787 WIFI_FEATURE_SOFT_AP;
5788
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305789 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5790 WIFI_FEATURE_SOFT_AP |
5791 WIFI_FEATURE_P2P;
5792
5793 /* Add more feature combinations here */
5794
5795 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5796 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5797 hddLog(LOG1, "Feature set matrix");
5798 for (i = 0; i < feature_sets; i++)
5799 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5800
5801 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5802 sizeof(u32) * feature_sets +
5803 NLMSG_HDRLEN);
5804
5805 if (reply_skb) {
5806 if (nla_put_u32(reply_skb,
5807 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5808 feature_sets) ||
5809 nla_put(reply_skb,
5810 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5811 sizeof(u32) * feature_sets, feature_set_matrix)) {
5812 hddLog(LOGE, FL("nla put fail"));
5813 kfree_skb(reply_skb);
5814 return -EINVAL;
5815 }
5816
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305817 ret = cfg80211_vendor_cmd_reply(reply_skb);
5818 EXIT();
5819 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305820 }
5821 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5822 return -ENOMEM;
5823
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305824}
5825
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305826static int
5827wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5828 struct wireless_dev *wdev,
5829 const void *data, int data_len)
5830{
5831 int ret = 0;
5832
5833 vos_ssr_protect(__func__);
5834 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5835 data_len);
5836 vos_ssr_unprotect(__func__);
5837
5838 return ret;
5839}
5840
c_manjeecfd1efb2015-09-25 19:32:34 +05305841
5842static int
5843__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5844 struct wireless_dev *wdev,
5845 const void *data, int data_len)
5846{
5847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5848 int ret;
5849 ENTER();
5850
5851 ret = wlan_hdd_validate_context(pHddCtx);
5852 if (0 != ret)
5853 {
5854 return ret;
5855 }
5856
5857 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5858 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5859 {
5860 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5861 return -EINVAL;
5862 }
5863 /*call common API for FW mem dump req*/
5864 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5865
Abhishek Singhc783fa72015-12-09 18:07:34 +05305866 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05305867 {
5868 /*indicate to userspace the status of fw mem dump */
5869 wlan_indicate_mem_dump_complete(true);
5870 }
5871 else
5872 {
5873 /*else send failure to userspace */
5874 wlan_indicate_mem_dump_complete(false);
5875 }
c_manjeecfd1efb2015-09-25 19:32:34 +05305876 EXIT();
5877 return ret;
5878}
5879
5880/**
5881 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5882 * @wiphy: pointer to wireless wiphy structure.
5883 * @wdev: pointer to wireless_dev structure.
5884 * @data: Pointer to the NL data.
5885 * @data_len:Length of @data
5886 *
5887 * This is called when wlan driver needs to get the firmware memory dump
5888 * via vendor specific command.
5889 *
5890 * Return: 0 on success, error number otherwise.
5891 */
5892
5893static int
5894wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305897{
5898 int ret = 0;
5899 vos_ssr_protect(__func__);
5900 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5901 data_len);
5902 vos_ssr_unprotect(__func__);
5903 return ret;
5904}
c_manjeecfd1efb2015-09-25 19:32:34 +05305905
Sushant Kaushik8e644982015-09-23 12:18:54 +05305906static const struct
5907nla_policy
5908qca_wlan_vendor_wifi_logger_start_policy
5909[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5910 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5911 = {.type = NLA_U32 },
5912 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5913 = {.type = NLA_U32 },
5914 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5915 = {.type = NLA_U32 },
5916};
5917
5918/**
5919 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5920 * or disable the collection of packet statistics from the firmware
5921 * @wiphy: WIPHY structure pointer
5922 * @wdev: Wireless device structure pointer
5923 * @data: Pointer to the data received
5924 * @data_len: Length of the data received
5925 *
5926 * This function is used to enable or disable the collection of packet
5927 * statistics from the firmware
5928 *
5929 * Return: 0 on success and errno on failure
5930 */
5931static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5932 struct wireless_dev *wdev,
5933 const void *data,
5934 int data_len)
5935{
5936 eHalStatus status;
5937 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5938 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5939 tAniWifiStartLog start_log;
5940
5941 status = wlan_hdd_validate_context(hdd_ctx);
5942 if (0 != status) {
5943 return -EINVAL;
5944 }
5945
5946 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5947 data, data_len,
5948 qca_wlan_vendor_wifi_logger_start_policy)) {
5949 hddLog(LOGE, FL("Invalid attribute"));
5950 return -EINVAL;
5951 }
5952
5953 /* Parse and fetch ring id */
5954 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5955 hddLog(LOGE, FL("attr ATTR failed"));
5956 return -EINVAL;
5957 }
5958 start_log.ringId = nla_get_u32(
5959 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5960 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5961
5962 /* Parse and fetch verbose level */
5963 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5964 hddLog(LOGE, FL("attr verbose_level failed"));
5965 return -EINVAL;
5966 }
5967 start_log.verboseLevel = nla_get_u32(
5968 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5969 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5970
5971 /* Parse and fetch flag */
5972 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5973 hddLog(LOGE, FL("attr flag failed"));
5974 return -EINVAL;
5975 }
5976 start_log.flag = nla_get_u32(
5977 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5978 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5979
5980 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305981 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5982 !vos_isPktStatsEnabled()))
5983
Sushant Kaushik8e644982015-09-23 12:18:54 +05305984 {
5985 hddLog(LOGE, FL("per pkt stats not enabled"));
5986 return -EINVAL;
5987 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305988
Sushant Kaushik33200572015-08-05 16:46:20 +05305989 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305990 return 0;
5991}
5992
5993/**
5994 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5995 * or disable the collection of packet statistics from the firmware
5996 * @wiphy: WIPHY structure pointer
5997 * @wdev: Wireless device structure pointer
5998 * @data: Pointer to the data received
5999 * @data_len: Length of the data received
6000 *
6001 * This function is used to enable or disable the collection of packet
6002 * statistics from the firmware
6003 *
6004 * Return: 0 on success and errno on failure
6005 */
6006static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6007 struct wireless_dev *wdev,
6008 const void *data,
6009 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306010{
6011 int ret = 0;
6012
6013 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306014
6015 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6016 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306017 vos_ssr_unprotect(__func__);
6018
6019 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306020}
6021
6022
Agarwal Ashish738843c2014-09-25 12:27:56 +05306023static const struct nla_policy
6024wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6025 +1] =
6026{
6027 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6028};
6029
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306030static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306031 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306032 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306033 int data_len)
6034{
6035 struct net_device *dev = wdev->netdev;
6036 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6037 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6038 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6039 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6040 eHalStatus status;
6041 u32 dfsFlag = 0;
6042
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306043 ENTER();
6044
Agarwal Ashish738843c2014-09-25 12:27:56 +05306045 status = wlan_hdd_validate_context(pHddCtx);
6046 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306047 return -EINVAL;
6048 }
6049 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6050 data, data_len,
6051 wlan_hdd_set_no_dfs_flag_config_policy)) {
6052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6053 return -EINVAL;
6054 }
6055
6056 /* Parse and fetch required bandwidth kbps */
6057 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6058 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6059 return -EINVAL;
6060 }
6061
6062 dfsFlag = nla_get_u32(
6063 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6064 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6065 dfsFlag);
6066
6067 pHddCtx->disable_dfs_flag = dfsFlag;
6068
6069 sme_disable_dfs_channel(hHal, dfsFlag);
6070 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306071
6072 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306073 return 0;
6074}
Atul Mittal115287b2014-07-08 13:26:33 +05306075
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306076static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6077 struct wireless_dev *wdev,
6078 const void *data,
6079 int data_len)
6080{
6081 int ret = 0;
6082
6083 vos_ssr_protect(__func__);
6084 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6085 vos_ssr_unprotect(__func__);
6086
6087 return ret;
6088
6089}
6090
Mukul Sharma2a271632014-10-13 14:59:01 +05306091const struct
6092nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6093{
6094 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6095 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6096};
6097
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306098static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306099 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306100{
6101
6102 u8 bssid[6] = {0};
6103 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6104 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6105 eHalStatus status = eHAL_STATUS_SUCCESS;
6106 v_U32_t isFwrRoamEnabled = FALSE;
6107 int ret;
6108
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306109 ENTER();
6110
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306111 ret = wlan_hdd_validate_context(pHddCtx);
6112 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306113 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306114 }
6115
6116 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6117 data, data_len,
6118 qca_wlan_vendor_attr);
6119 if (ret){
6120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6121 return -EINVAL;
6122 }
6123
6124 /* Parse and fetch Enable flag */
6125 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6127 return -EINVAL;
6128 }
6129
6130 isFwrRoamEnabled = nla_get_u32(
6131 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6132
6133 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6134
6135 /* Parse and fetch bssid */
6136 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6138 return -EINVAL;
6139 }
6140
6141 memcpy(bssid, nla_data(
6142 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6143 sizeof(bssid));
6144 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6145
6146 //Update roaming
6147 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306148 if (!HAL_STATUS_SUCCESS(status)) {
6149 hddLog(LOGE,
6150 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6151 return -EINVAL;
6152 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306153 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306154 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306155}
6156
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306157static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6158 struct wireless_dev *wdev, const void *data, int data_len)
6159{
6160 int ret = 0;
6161
6162 vos_ssr_protect(__func__);
6163 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6164 vos_ssr_unprotect(__func__);
6165
6166 return ret;
6167}
6168
Sushant Kaushik847890c2015-09-28 16:05:17 +05306169static const struct
6170nla_policy
6171qca_wlan_vendor_get_wifi_info_policy[
6172 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6173 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6174 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6175};
6176
6177
6178/**
6179 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6180 * @wiphy: pointer to wireless wiphy structure.
6181 * @wdev: pointer to wireless_dev structure.
6182 * @data: Pointer to the data to be passed via vendor interface
6183 * @data_len:Length of the data to be passed
6184 *
6185 * This is called when wlan driver needs to send wifi driver related info
6186 * (driver/fw version) to the user space application upon request.
6187 *
6188 * Return: Return the Success or Failure code.
6189 */
6190static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6191 struct wireless_dev *wdev,
6192 const void *data, int data_len)
6193{
6194 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6195 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6196 tSirVersionString version;
6197 uint32 version_len;
6198 uint8 attr;
6199 int status;
6200 struct sk_buff *reply_skb = NULL;
6201
6202 if (VOS_FTM_MODE == hdd_get_conparam()) {
6203 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6204 return -EINVAL;
6205 }
6206
6207 status = wlan_hdd_validate_context(hdd_ctx);
6208 if (0 != status) {
6209 hddLog(LOGE, FL("HDD context is not valid"));
6210 return -EINVAL;
6211 }
6212
6213 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6214 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6215 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6216 return -EINVAL;
6217 }
6218
6219 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6220 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6221 QWLAN_VERSIONSTR);
6222 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6223 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6224 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6225 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6226 hdd_ctx->fw_Version);
6227 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6228 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6229 } else {
6230 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6231 return -EINVAL;
6232 }
6233
6234 version_len = strlen(version);
6235 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6236 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6237 if (!reply_skb) {
6238 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6239 return -ENOMEM;
6240 }
6241
6242 if (nla_put(reply_skb, attr, version_len, version)) {
6243 hddLog(LOGE, FL("nla put fail"));
6244 kfree_skb(reply_skb);
6245 return -EINVAL;
6246 }
6247
6248 return cfg80211_vendor_cmd_reply(reply_skb);
6249}
6250
6251/**
6252 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6253 * @wiphy: pointer to wireless wiphy structure.
6254 * @wdev: pointer to wireless_dev structure.
6255 * @data: Pointer to the data to be passed via vendor interface
6256 * @data_len:Length of the data to be passed
6257 * @data_len: Length of the data received
6258 *
6259 * This function is used to enable or disable the collection of packet
6260 * statistics from the firmware
6261 *
6262 * Return: 0 on success and errno on failure
6263 */
6264
6265static int
6266wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6267 struct wireless_dev *wdev,
6268 const void *data, int data_len)
6269
6270
6271{
6272 int ret = 0;
6273
6274 vos_ssr_protect(__func__);
6275 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6276 wdev, data, data_len);
6277 vos_ssr_unprotect(__func__);
6278
6279 return ret;
6280}
6281
6282
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306283/*
6284 * define short names for the global vendor params
6285 * used by __wlan_hdd_cfg80211_monitor_rssi()
6286 */
6287#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6288#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6289#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6290#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6291#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6292
6293/**---------------------------------------------------------------------------
6294
6295 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6296 monitor start is completed successfully.
6297
6298 \return - None
6299
6300 --------------------------------------------------------------------------*/
6301void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6302{
6303 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6304
6305 if (NULL == pHddCtx)
6306 {
6307 hddLog(VOS_TRACE_LEVEL_ERROR,
6308 "%s: HDD context is NULL",__func__);
6309 return;
6310 }
6311
6312 if (VOS_STATUS_SUCCESS == status)
6313 {
6314 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6315 }
6316 else
6317 {
6318 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6319 }
6320
6321 return;
6322}
6323
6324/**---------------------------------------------------------------------------
6325
6326 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6327 stop is completed successfully.
6328
6329 \return - None
6330
6331 --------------------------------------------------------------------------*/
6332void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6333{
6334 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6335
6336 if (NULL == pHddCtx)
6337 {
6338 hddLog(VOS_TRACE_LEVEL_ERROR,
6339 "%s: HDD context is NULL",__func__);
6340 return;
6341 }
6342
6343 if (VOS_STATUS_SUCCESS == status)
6344 {
6345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6346 }
6347 else
6348 {
6349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6350 }
6351
6352 return;
6353}
6354
6355/**
6356 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6357 * @wiphy: Pointer to wireless phy
6358 * @wdev: Pointer to wireless device
6359 * @data: Pointer to data
6360 * @data_len: Data length
6361 *
6362 * Return: 0 on success, negative errno on failure
6363 */
6364
6365static int
6366__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6367 struct wireless_dev *wdev,
6368 const void *data,
6369 int data_len)
6370{
6371 struct net_device *dev = wdev->netdev;
6372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6373 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6374 hdd_station_ctx_t *pHddStaCtx;
6375 struct nlattr *tb[PARAM_MAX + 1];
6376 tpSirRssiMonitorReq pReq;
6377 eHalStatus status;
6378 int ret;
6379 uint32_t control;
6380 static const struct nla_policy policy[PARAM_MAX + 1] = {
6381 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6382 [PARAM_CONTROL] = { .type = NLA_U32 },
6383 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6384 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6385 };
6386
6387 ENTER();
6388
6389 ret = wlan_hdd_validate_context(hdd_ctx);
6390 if (0 != ret) {
6391 return -EINVAL;
6392 }
6393
6394 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6395 hddLog(LOGE, FL("Not in Connected state!"));
6396 return -ENOTSUPP;
6397 }
6398
6399 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6400 hddLog(LOGE, FL("Invalid ATTR"));
6401 return -EINVAL;
6402 }
6403
6404 if (!tb[PARAM_REQUEST_ID]) {
6405 hddLog(LOGE, FL("attr request id failed"));
6406 return -EINVAL;
6407 }
6408
6409 if (!tb[PARAM_CONTROL]) {
6410 hddLog(LOGE, FL("attr control failed"));
6411 return -EINVAL;
6412 }
6413
6414 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6415
6416 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6417 if(NULL == pReq)
6418 {
6419 hddLog(LOGE,
6420 FL("vos_mem_alloc failed "));
6421 return eHAL_STATUS_FAILED_ALLOC;
6422 }
6423 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6424
6425 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6426 pReq->sessionId = pAdapter->sessionId;
6427 pReq->rssiMonitorCbContext = hdd_ctx;
6428 control = nla_get_u32(tb[PARAM_CONTROL]);
6429 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6430
6431 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6432 pReq->requestId, pReq->sessionId, control);
6433
6434 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6435 if (!tb[PARAM_MIN_RSSI]) {
6436 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306437 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306438 }
6439
6440 if (!tb[PARAM_MAX_RSSI]) {
6441 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306442 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306443 }
6444
6445 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6446 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6447 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6448
6449 if (!(pReq->minRssi < pReq->maxRssi)) {
6450 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6451 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306452 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306453 }
6454 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6455 pReq->minRssi, pReq->maxRssi);
6456 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6457
6458 }
6459 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6460 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6461 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6462 }
6463 else {
6464 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306465 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306466 }
6467
6468 if (!HAL_STATUS_SUCCESS(status)) {
6469 hddLog(LOGE,
6470 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306471 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306472 }
6473
6474 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306475fail:
6476 vos_mem_free(pReq);
6477 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306478}
6479
6480/*
6481 * done with short names for the global vendor params
6482 * used by __wlan_hdd_cfg80211_monitor_rssi()
6483 */
6484#undef PARAM_MAX
6485#undef PARAM_CONTROL
6486#undef PARAM_REQUEST_ID
6487#undef PARAM_MAX_RSSI
6488#undef PARAM_MIN_RSSI
6489
6490/**
6491 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6492 * @wiphy: wiphy structure pointer
6493 * @wdev: Wireless device structure pointer
6494 * @data: Pointer to the data received
6495 * @data_len: Length of @data
6496 *
6497 * Return: 0 on success; errno on failure
6498 */
6499static int
6500wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6501 const void *data, int data_len)
6502{
6503 int ret;
6504
6505 vos_ssr_protect(__func__);
6506 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6507 vos_ssr_unprotect(__func__);
6508
6509 return ret;
6510}
6511
6512/**
6513 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6514 * @hddctx: HDD context
6515 * @data: rssi breached event data
6516 *
6517 * This function reads the rssi breached event %data and fill in the skb with
6518 * NL attributes and send up the NL event.
6519 * This callback execute in atomic context and must not invoke any
6520 * blocking calls.
6521 *
6522 * Return: none
6523 */
6524void hdd_rssi_threshold_breached_cb(void *hddctx,
6525 struct rssi_breach_event *data)
6526{
6527 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6528 int status;
6529 struct sk_buff *skb;
6530
6531 ENTER();
6532 status = wlan_hdd_validate_context(pHddCtx);
6533
6534 if (0 != status) {
6535 return;
6536 }
6537
6538 if (!data) {
6539 hddLog(LOGE, FL("data is null"));
6540 return;
6541 }
6542
6543 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6544#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6545 NULL,
6546#endif
6547 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6548 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6549 GFP_KERNEL);
6550
6551 if (!skb) {
6552 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6553 return;
6554 }
6555
6556 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6557 data->request_id, data->curr_rssi);
6558 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6559 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6560
6561 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6562 data->request_id) ||
6563 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6564 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6565 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6566 data->curr_rssi)) {
6567 hddLog(LOGE, FL("nla put fail"));
6568 goto fail;
6569 }
6570
6571 cfg80211_vendor_event(skb, GFP_KERNEL);
6572 return;
6573
6574fail:
6575 kfree_skb(skb);
6576 return;
6577}
6578
6579
6580
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306581/**
6582 * __wlan_hdd_cfg80211_setband() - set band
6583 * @wiphy: Pointer to wireless phy
6584 * @wdev: Pointer to wireless device
6585 * @data: Pointer to data
6586 * @data_len: Data length
6587 *
6588 * Return: 0 on success, negative errno on failure
6589 */
6590static int
6591__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6592 struct wireless_dev *wdev,
6593 const void *data,
6594 int data_len)
6595{
6596 struct net_device *dev = wdev->netdev;
6597 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6598 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6599 int ret;
6600 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6601 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6602
6603 ENTER();
6604
6605 ret = wlan_hdd_validate_context(hdd_ctx);
6606 if (0 != ret) {
6607 hddLog(LOGE, FL("HDD context is not valid"));
6608 return ret;
6609 }
6610
6611 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6612 policy)) {
6613 hddLog(LOGE, FL("Invalid ATTR"));
6614 return -EINVAL;
6615 }
6616
6617 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6618 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6619 return -EINVAL;
6620 }
6621
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306622 hdd_ctx->isSetBandByNL = TRUE;
6623 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306624 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306625 hdd_ctx->isSetBandByNL = FALSE;
6626
6627 EXIT();
6628 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306629}
6630
6631/**
6632 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6633 * @wiphy: wiphy structure pointer
6634 * @wdev: Wireless device structure pointer
6635 * @data: Pointer to the data received
6636 * @data_len: Length of @data
6637 *
6638 * Return: 0 on success; errno on failure
6639 */
6640static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6641 struct wireless_dev *wdev,
6642 const void *data,
6643 int data_len)
6644{
6645 int ret = 0;
6646
6647 vos_ssr_protect(__func__);
6648 ret = __wlan_hdd_cfg80211_setband(wiphy,
6649 wdev, data, data_len);
6650 vos_ssr_unprotect(__func__);
6651
6652 return ret;
6653}
6654
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306655#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6656/**
6657 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6658 * @hdd_ctx: HDD context
6659 * @request_id: [input] request id
6660 * @pattern_id: [output] pattern id
6661 *
6662 * This function loops through request id to pattern id array
6663 * if the slot is available, store the request id and return pattern id
6664 * if entry exists, return the pattern id
6665 *
6666 * Return: 0 on success and errno on failure
6667 */
6668static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6669 uint32_t request_id,
6670 uint8_t *pattern_id)
6671{
6672 uint32_t i;
6673
6674 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6675 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6676 {
6677 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6678 {
6679 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6680 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6681 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6682 return 0;
6683 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6684 request_id) {
6685 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6686 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6687 return 0;
6688 }
6689 }
6690 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6691 return -EINVAL;
6692}
6693
6694/**
6695 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6696 * @hdd_ctx: HDD context
6697 * @request_id: [input] request id
6698 * @pattern_id: [output] pattern id
6699 *
6700 * This function loops through request id to pattern id array
6701 * reset request id to 0 (slot available again) and
6702 * return pattern id
6703 *
6704 * Return: 0 on success and errno on failure
6705 */
6706static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6707 uint32_t request_id,
6708 uint8_t *pattern_id)
6709{
6710 uint32_t i;
6711
6712 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6713 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6714 {
6715 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6716 {
6717 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6718 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6719 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6720 return 0;
6721 }
6722 }
6723 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6724 return -EINVAL;
6725}
6726
6727
6728/*
6729 * define short names for the global vendor params
6730 * used by __wlan_hdd_cfg80211_offloaded_packets()
6731 */
6732#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6733#define PARAM_REQUEST_ID \
6734 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6735#define PARAM_CONTROL \
6736 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6737#define PARAM_IP_PACKET \
6738 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6739#define PARAM_SRC_MAC_ADDR \
6740 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6741#define PARAM_DST_MAC_ADDR \
6742 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6743#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6744
6745/**
6746 * wlan_hdd_add_tx_ptrn() - add tx pattern
6747 * @adapter: adapter pointer
6748 * @hdd_ctx: hdd context
6749 * @tb: nl attributes
6750 *
6751 * This function reads the NL attributes and forms a AddTxPtrn message
6752 * posts it to SME.
6753 *
6754 */
6755static int
6756wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6757 struct nlattr **tb)
6758{
6759 struct sSirAddPeriodicTxPtrn *add_req;
6760 eHalStatus status;
6761 uint32_t request_id, ret, len;
6762 uint8_t pattern_id = 0;
6763 v_MACADDR_t dst_addr;
6764 uint16_t eth_type = htons(ETH_P_IP);
6765
6766 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6767 {
6768 hddLog(LOGE, FL("Not in Connected state!"));
6769 return -ENOTSUPP;
6770 }
6771
6772 add_req = vos_mem_malloc(sizeof(*add_req));
6773 if (!add_req)
6774 {
6775 hddLog(LOGE, FL("memory allocation failed"));
6776 return -ENOMEM;
6777 }
6778
6779 /* Parse and fetch request Id */
6780 if (!tb[PARAM_REQUEST_ID])
6781 {
6782 hddLog(LOGE, FL("attr request id failed"));
6783 goto fail;
6784 }
6785
6786 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6787 hddLog(LOG1, FL("Request Id: %u"), request_id);
6788 if (request_id == 0)
6789 {
6790 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306791 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306792 }
6793
6794 if (!tb[PARAM_PERIOD])
6795 {
6796 hddLog(LOGE, FL("attr period failed"));
6797 goto fail;
6798 }
6799 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6800 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6801 if (add_req->usPtrnIntervalMs == 0)
6802 {
6803 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6804 goto fail;
6805 }
6806
6807 if (!tb[PARAM_SRC_MAC_ADDR])
6808 {
6809 hddLog(LOGE, FL("attr source mac address failed"));
6810 goto fail;
6811 }
6812 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6813 VOS_MAC_ADDR_SIZE);
6814 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6815 MAC_ADDR_ARRAY(add_req->macAddress));
6816
6817 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6818 VOS_MAC_ADDR_SIZE))
6819 {
6820 hddLog(LOGE,
6821 FL("input src mac address and connected ap bssid are different"));
6822 goto fail;
6823 }
6824
6825 if (!tb[PARAM_DST_MAC_ADDR])
6826 {
6827 hddLog(LOGE, FL("attr dst mac address failed"));
6828 goto fail;
6829 }
6830 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6831 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6832 MAC_ADDR_ARRAY(dst_addr.bytes));
6833
6834 if (!tb[PARAM_IP_PACKET])
6835 {
6836 hddLog(LOGE, FL("attr ip packet failed"));
6837 goto fail;
6838 }
6839 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6840 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6841
6842 if (add_req->ucPtrnSize < 0 ||
6843 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6844 HDD_ETH_HEADER_LEN))
6845 {
6846 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6847 add_req->ucPtrnSize);
6848 goto fail;
6849 }
6850
6851 len = 0;
6852 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6853 len += VOS_MAC_ADDR_SIZE;
6854 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6855 VOS_MAC_ADDR_SIZE);
6856 len += VOS_MAC_ADDR_SIZE;
6857 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6858 len += 2;
6859
6860 /*
6861 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6862 * ------------------------------------------------------------
6863 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6864 * ------------------------------------------------------------
6865 */
6866 vos_mem_copy(&add_req->ucPattern[len],
6867 nla_data(tb[PARAM_IP_PACKET]),
6868 add_req->ucPtrnSize);
6869 add_req->ucPtrnSize += len;
6870
6871 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6872 add_req->ucPattern, add_req->ucPtrnSize);
6873
6874 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6875 if (ret)
6876 {
6877 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6878 goto fail;
6879 }
6880 add_req->ucPtrnId = pattern_id;
6881 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6882
6883 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6884 if (!HAL_STATUS_SUCCESS(status))
6885 {
6886 hddLog(LOGE,
6887 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6888 goto fail;
6889 }
6890
6891 EXIT();
6892 vos_mem_free(add_req);
6893 return 0;
6894
6895fail:
6896 vos_mem_free(add_req);
6897 return -EINVAL;
6898}
6899
6900/**
6901 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6902 * @adapter: adapter pointer
6903 * @hdd_ctx: hdd context
6904 * @tb: nl attributes
6905 *
6906 * This function reads the NL attributes and forms a DelTxPtrn message
6907 * posts it to SME.
6908 *
6909 */
6910static int
6911wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6912 struct nlattr **tb)
6913{
6914 struct sSirDelPeriodicTxPtrn *del_req;
6915 eHalStatus status;
6916 uint32_t request_id, ret;
6917 uint8_t pattern_id = 0;
6918
6919 /* Parse and fetch request Id */
6920 if (!tb[PARAM_REQUEST_ID])
6921 {
6922 hddLog(LOGE, FL("attr request id failed"));
6923 return -EINVAL;
6924 }
6925 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6926 if (request_id == 0)
6927 {
6928 hddLog(LOGE, FL("request_id cannot be zero"));
6929 return -EINVAL;
6930 }
6931
6932 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6933 if (ret)
6934 {
6935 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6936 return -EINVAL;
6937 }
6938
6939 del_req = vos_mem_malloc(sizeof(*del_req));
6940 if (!del_req)
6941 {
6942 hddLog(LOGE, FL("memory allocation failed"));
6943 return -ENOMEM;
6944 }
6945
6946 vos_mem_set(del_req, sizeof(*del_req), 0);
6947 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6948 VOS_MAC_ADDR_SIZE);
6949 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6950 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6951 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6952 request_id, pattern_id, del_req->ucPatternIdBitmap);
6953
6954 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6955 if (!HAL_STATUS_SUCCESS(status))
6956 {
6957 hddLog(LOGE,
6958 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6959 goto fail;
6960 }
6961
6962 EXIT();
6963 vos_mem_free(del_req);
6964 return 0;
6965
6966fail:
6967 vos_mem_free(del_req);
6968 return -EINVAL;
6969}
6970
6971
6972/**
6973 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6974 * @wiphy: Pointer to wireless phy
6975 * @wdev: Pointer to wireless device
6976 * @data: Pointer to data
6977 * @data_len: Data length
6978 *
6979 * Return: 0 on success, negative errno on failure
6980 */
6981static int
6982__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6983 struct wireless_dev *wdev,
6984 const void *data,
6985 int data_len)
6986{
6987 struct net_device *dev = wdev->netdev;
6988 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6989 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6990 struct nlattr *tb[PARAM_MAX + 1];
6991 uint8_t control;
6992 int ret;
6993 static const struct nla_policy policy[PARAM_MAX + 1] =
6994 {
6995 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6996 [PARAM_CONTROL] = { .type = NLA_U32 },
6997 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6998 .len = VOS_MAC_ADDR_SIZE },
6999 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7000 .len = VOS_MAC_ADDR_SIZE },
7001 [PARAM_PERIOD] = { .type = NLA_U32 },
7002 };
7003
7004 ENTER();
7005
7006 ret = wlan_hdd_validate_context(hdd_ctx);
7007 if (0 != ret)
7008 {
7009 hddLog(LOGE, FL("HDD context is not valid"));
7010 return ret;
7011 }
7012
7013 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7014 {
7015 hddLog(LOGE,
7016 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7017 return -ENOTSUPP;
7018 }
7019
7020 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7021 {
7022 hddLog(LOGE, FL("Invalid ATTR"));
7023 return -EINVAL;
7024 }
7025
7026 if (!tb[PARAM_CONTROL])
7027 {
7028 hddLog(LOGE, FL("attr control failed"));
7029 return -EINVAL;
7030 }
7031 control = nla_get_u32(tb[PARAM_CONTROL]);
7032 hddLog(LOG1, FL("Control: %d"), control);
7033
7034 if (control == WLAN_START_OFFLOADED_PACKETS)
7035 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7036 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7037 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7038 else
7039 {
7040 hddLog(LOGE, FL("Invalid control: %d"), control);
7041 return -EINVAL;
7042 }
7043}
7044
7045/*
7046 * done with short names for the global vendor params
7047 * used by __wlan_hdd_cfg80211_offloaded_packets()
7048 */
7049#undef PARAM_MAX
7050#undef PARAM_REQUEST_ID
7051#undef PARAM_CONTROL
7052#undef PARAM_IP_PACKET
7053#undef PARAM_SRC_MAC_ADDR
7054#undef PARAM_DST_MAC_ADDR
7055#undef PARAM_PERIOD
7056
7057/**
7058 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7059 * @wiphy: wiphy structure pointer
7060 * @wdev: Wireless device structure pointer
7061 * @data: Pointer to the data received
7062 * @data_len: Length of @data
7063 *
7064 * Return: 0 on success; errno on failure
7065 */
7066static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7067 struct wireless_dev *wdev,
7068 const void *data,
7069 int data_len)
7070{
7071 int ret = 0;
7072
7073 vos_ssr_protect(__func__);
7074 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7075 wdev, data, data_len);
7076 vos_ssr_unprotect(__func__);
7077
7078 return ret;
7079}
7080#endif
7081
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307082static const struct
7083nla_policy
7084qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7085 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7086};
7087
7088/**
7089 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7090 * get link properties like nss, rate flags and operating frequency for
7091 * the connection with the given peer.
7092 * @wiphy: WIPHY structure pointer
7093 * @wdev: Wireless device structure pointer
7094 * @data: Pointer to the data received
7095 * @data_len: Length of the data received
7096 *
7097 * This function return the above link properties on success.
7098 *
7099 * Return: 0 on success and errno on failure
7100 */
7101static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7102 struct wireless_dev *wdev,
7103 const void *data,
7104 int data_len)
7105{
7106 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7107 struct net_device *dev = wdev->netdev;
7108 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7109 hdd_station_ctx_t *hdd_sta_ctx;
7110 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7111 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7112 uint32_t sta_id;
7113 struct sk_buff *reply_skb;
7114 uint32_t rate_flags = 0;
7115 uint8_t nss;
7116 uint8_t final_rate_flags = 0;
7117 uint32_t freq;
7118 v_CONTEXT_t pVosContext = NULL;
7119 ptSapContext pSapCtx = NULL;
7120
7121 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7123 return -EINVAL;
7124 }
7125
7126 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7127 qca_wlan_vendor_attr_policy)) {
7128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7129 return -EINVAL;
7130 }
7131
7132 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7133 hddLog(VOS_TRACE_LEVEL_ERROR,
7134 FL("Attribute peerMac not provided for mode=%d"),
7135 adapter->device_mode);
7136 return -EINVAL;
7137 }
7138
7139 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7140 sizeof(peer_mac));
7141 hddLog(VOS_TRACE_LEVEL_INFO,
7142 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7143 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7144
7145 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7146 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7147 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7148 if ((hdd_sta_ctx->conn_info.connState !=
7149 eConnectionState_Associated) ||
7150 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7151 VOS_MAC_ADDRESS_LEN)) {
7152 hddLog(VOS_TRACE_LEVEL_ERROR,
7153 FL("Not Associated to 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 hdd_sta_ctx->conn_info.operationChannel);
7161 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7162
7163 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7164 adapter->device_mode == WLAN_HDD_SOFTAP) {
7165
7166 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7167 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7168 if(pSapCtx == NULL){
7169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7170 FL("psapCtx is NULL"));
7171 return -ENOENT;
7172 }
7173
7174
7175 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7176 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7177 !vos_is_macaddr_broadcast(
7178 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7179 vos_mem_compare(
7180 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7181 peer_mac, VOS_MAC_ADDRESS_LEN))
7182 break;
7183 }
7184
7185 if (WLAN_MAX_STA_COUNT == sta_id) {
7186 hddLog(VOS_TRACE_LEVEL_ERROR,
7187 FL("No active peer with mac="MAC_ADDRESS_STR),
7188 MAC_ADDR_ARRAY(peer_mac));
7189 return -EINVAL;
7190 }
7191
7192 nss = 1; //pronto supports only one spatial stream
7193 freq = vos_chan_to_freq(
7194 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7195 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7196 } else {
7197 hddLog(VOS_TRACE_LEVEL_ERROR,
7198 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7199 MAC_ADDR_ARRAY(peer_mac));
7200 return -EINVAL;
7201 }
7202
7203 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7204 if (rate_flags & eHAL_TX_RATE_VHT80) {
7205 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7206 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7207 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7208 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7209 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7210 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7211 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7212 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7213 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7214 if (rate_flags & eHAL_TX_RATE_HT40)
7215 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7216 }
7217
7218 if (rate_flags & eHAL_TX_RATE_SGI) {
7219 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7220 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7221 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7222 }
7223 }
7224
7225 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7226 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7227
7228 if (NULL == reply_skb) {
7229 hddLog(VOS_TRACE_LEVEL_ERROR,
7230 FL("getLinkProperties: skb alloc failed"));
7231 return -EINVAL;
7232 }
7233
7234 if (nla_put_u8(reply_skb,
7235 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7236 nss) ||
7237 nla_put_u8(reply_skb,
7238 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7239 final_rate_flags) ||
7240 nla_put_u32(reply_skb,
7241 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7242 freq)) {
7243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7244 kfree_skb(reply_skb);
7245 return -EINVAL;
7246 }
7247
7248 return cfg80211_vendor_cmd_reply(reply_skb);
7249}
7250
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307251#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7252#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7253#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7254#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307255#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7256 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307257
7258/**
7259 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7260 * vendor command
7261 *
7262 * @wiphy: wiphy device pointer
7263 * @wdev: wireless device pointer
7264 * @data: Vendor command data buffer
7265 * @data_len: Buffer length
7266 *
7267 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7268 *
7269 * Return: EOK or other error codes.
7270 */
7271
7272static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7273 struct wireless_dev *wdev,
7274 const void *data,
7275 int data_len)
7276{
7277 struct net_device *dev = wdev->netdev;
7278 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7279 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7280 hdd_station_ctx_t *pHddStaCtx;
7281 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7282 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307283 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307284 eHalStatus status;
7285 int ret_val;
7286 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7287 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7288 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307289 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7290 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7291 { .type = NLA_U32},
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307292 };
7293
7294 ENTER();
7295
7296 if (VOS_FTM_MODE == hdd_get_conparam()) {
7297 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7298 return -EINVAL;
7299 }
7300
7301 ret_val = wlan_hdd_validate_context(pHddCtx);
7302 if (ret_val) {
7303 return ret_val;
7304 }
7305
7306 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7307
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307308 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7309 hddLog(LOGE, FL("Invalid ATTR"));
7310 return -EINVAL;
7311 }
7312
7313 /* check the Wifi Capability */
7314 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7315 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7316 {
7317 hddLog(VOS_TRACE_LEVEL_ERROR,
7318 FL("WIFICONFIG not supported by Firmware"));
7319 return -EINVAL;
7320 }
7321
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307322 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7323 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7324 modifyRoamParamsReq.value =
7325 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7326
7327 if (eHAL_STATUS_SUCCESS !=
7328 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7329 {
7330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7331 ret_val = -EINVAL;
7332 }
7333 return ret_val;
7334 }
7335
7336 /* Moved this down in order to provide provision to set beacon
7337 * miss penalty count irrespective of connection state.
7338 */
7339 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7340 hddLog(LOGE, FL("Not in Connected state!"));
7341 return -ENOTSUPP;
7342 }
7343
7344 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307345
7346 if (!pReq) {
7347 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7348 "%s: Not able to allocate memory for tSetWifiConfigParams",
7349 __func__);
7350 return eHAL_STATUS_E_MALLOC_FAILED;
7351 }
7352
7353 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7354
7355 pReq->sessionId = pAdapter->sessionId;
7356 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7357
7358 if (tb[PARAM_MODULATED_DTIM]) {
7359 pReq->paramValue = nla_get_u32(
7360 tb[PARAM_MODULATED_DTIM]);
7361 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7362 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307363 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307364 hdd_set_pwrparams(pHddCtx);
7365 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7366 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7367
7368 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7369 iw_full_power_cbfn, pAdapter,
7370 eSME_FULL_PWR_NEEDED_BY_HDD);
7371 }
7372 else
7373 {
7374 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7375 }
7376 }
7377
7378 if (tb[PARAM_STATS_AVG_FACTOR]) {
7379 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7380 pReq->paramValue = nla_get_u16(
7381 tb[PARAM_STATS_AVG_FACTOR]);
7382 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7383 pReq->paramType, pReq->paramValue);
7384 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7385
7386 if (eHAL_STATUS_SUCCESS != status)
7387 {
7388 vos_mem_free(pReq);
7389 pReq = NULL;
7390 ret_val = -EPERM;
7391 return ret_val;
7392 }
7393 }
7394
7395
7396 if (tb[PARAM_GUARD_TIME]) {
7397 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7398 pReq->paramValue = nla_get_u32(
7399 tb[PARAM_GUARD_TIME]);
7400 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7401 pReq->paramType, pReq->paramValue);
7402 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7403
7404 if (eHAL_STATUS_SUCCESS != status)
7405 {
7406 vos_mem_free(pReq);
7407 pReq = NULL;
7408 ret_val = -EPERM;
7409 return ret_val;
7410 }
7411
7412 }
7413
7414 EXIT();
7415 return ret_val;
7416}
7417
7418/**
7419 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7420 * vendor command
7421 *
7422 * @wiphy: wiphy device pointer
7423 * @wdev: wireless device pointer
7424 * @data: Vendor command data buffer
7425 * @data_len: Buffer length
7426 *
7427 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7428 *
7429 * Return: EOK or other error codes.
7430 */
7431static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7432 struct wireless_dev *wdev,
7433 const void *data,
7434 int data_len)
7435{
7436 int ret;
7437
7438 vos_ssr_protect(__func__);
7439 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7440 data, data_len);
7441 vos_ssr_unprotect(__func__);
7442
7443 return ret;
7444}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307445const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7446{
Mukul Sharma2a271632014-10-13 14:59:01 +05307447 {
7448 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7449 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7450 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7451 WIPHY_VENDOR_CMD_NEED_NETDEV |
7452 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307453 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307454 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307455
7456 {
7457 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7458 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7459 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7460 WIPHY_VENDOR_CMD_NEED_NETDEV |
7461 WIPHY_VENDOR_CMD_NEED_RUNNING,
7462 .doit = wlan_hdd_cfg80211_nan_request
7463 },
7464
Sunil Duttc69bccb2014-05-26 21:30:20 +05307465#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7466 {
7467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7470 WIPHY_VENDOR_CMD_NEED_NETDEV |
7471 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307472 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307473 },
7474
7475 {
7476 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7477 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7478 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7479 WIPHY_VENDOR_CMD_NEED_NETDEV |
7480 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307481 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307482 },
7483
7484 {
7485 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7486 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7487 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7488 WIPHY_VENDOR_CMD_NEED_NETDEV |
7489 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307490 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307491 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307492#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307493#ifdef WLAN_FEATURE_EXTSCAN
7494 {
7495 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7496 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7497 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7498 WIPHY_VENDOR_CMD_NEED_NETDEV |
7499 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307500 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307501 },
7502 {
7503 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7504 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7505 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7506 WIPHY_VENDOR_CMD_NEED_NETDEV |
7507 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307508 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307509 },
7510 {
7511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7513 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7514 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307515 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307516 },
7517 {
7518 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7519 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7520 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7521 WIPHY_VENDOR_CMD_NEED_NETDEV |
7522 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307523 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307524 },
7525 {
7526 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7527 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7528 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7529 WIPHY_VENDOR_CMD_NEED_NETDEV |
7530 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307531 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307532 },
7533 {
7534 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7535 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
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_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307540 },
7541 {
7542 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7543 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
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_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307548 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307549 {
7550 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7551 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7552 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7553 WIPHY_VENDOR_CMD_NEED_NETDEV |
7554 WIPHY_VENDOR_CMD_NEED_RUNNING,
7555 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7556 },
7557 {
7558 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7559 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7560 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7561 WIPHY_VENDOR_CMD_NEED_NETDEV |
7562 WIPHY_VENDOR_CMD_NEED_RUNNING,
7563 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7564 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307565#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307566/*EXT TDLS*/
7567 {
7568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7571 WIPHY_VENDOR_CMD_NEED_NETDEV |
7572 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307573 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307574 },
7575 {
7576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7579 WIPHY_VENDOR_CMD_NEED_NETDEV |
7580 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307581 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307582 },
7583 {
7584 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7585 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7586 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7587 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307588 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307589 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307590 {
7591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7594 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307595 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307596 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307597 {
7598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7601 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307602 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307603 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307604 {
7605 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7606 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7607 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7608 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307609 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307610 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307611 {
7612 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7613 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7614 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7615 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307616 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307617 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307618 {
7619 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307620 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7621 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7622 WIPHY_VENDOR_CMD_NEED_NETDEV |
7623 WIPHY_VENDOR_CMD_NEED_RUNNING,
7624 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7625 },
7626 {
7627 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307628 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7629 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7630 WIPHY_VENDOR_CMD_NEED_NETDEV |
7631 WIPHY_VENDOR_CMD_NEED_RUNNING,
7632 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307633 },
7634 {
7635 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7636 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7637 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7638 WIPHY_VENDOR_CMD_NEED_NETDEV,
7639 .doit = wlan_hdd_cfg80211_wifi_logger_start
7640 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307641 {
7642 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7643 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
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_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307648 },
7649 {
7650 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7651 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
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_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307656 },
7657 {
7658 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7659 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7660 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7661 WIPHY_VENDOR_CMD_NEED_NETDEV |
7662 WIPHY_VENDOR_CMD_NEED_RUNNING,
7663 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307664 },
7665#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7666 {
7667 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7668 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7669 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7670 WIPHY_VENDOR_CMD_NEED_NETDEV |
7671 WIPHY_VENDOR_CMD_NEED_RUNNING,
7672 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307673 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307674#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307675 {
7676 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7677 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7678 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7679 WIPHY_VENDOR_CMD_NEED_NETDEV |
7680 WIPHY_VENDOR_CMD_NEED_RUNNING,
7681 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307682 },
7683 {
7684 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7685 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7686 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7687 WIPHY_VENDOR_CMD_NEED_NETDEV |
7688 WIPHY_VENDOR_CMD_NEED_RUNNING,
7689 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307690 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307691};
7692
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007693/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307694static const
7695struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007696{
7697#ifdef FEATURE_WLAN_CH_AVOID
7698 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307699 .vendor_id = QCA_NL80211_VENDOR_ID,
7700 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007701 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307702#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7703#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7704 {
7705 /* Index = 1*/
7706 .vendor_id = QCA_NL80211_VENDOR_ID,
7707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7708 },
7709 {
7710 /* Index = 2*/
7711 .vendor_id = QCA_NL80211_VENDOR_ID,
7712 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7713 },
7714 {
7715 /* Index = 3*/
7716 .vendor_id = QCA_NL80211_VENDOR_ID,
7717 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7718 },
7719 {
7720 /* Index = 4*/
7721 .vendor_id = QCA_NL80211_VENDOR_ID,
7722 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7723 },
7724 {
7725 /* Index = 5*/
7726 .vendor_id = QCA_NL80211_VENDOR_ID,
7727 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7728 },
7729 {
7730 /* Index = 6*/
7731 .vendor_id = QCA_NL80211_VENDOR_ID,
7732 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7733 },
7734#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307735#ifdef WLAN_FEATURE_EXTSCAN
7736 {
7737 .vendor_id = QCA_NL80211_VENDOR_ID,
7738 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7739 },
7740 {
7741 .vendor_id = QCA_NL80211_VENDOR_ID,
7742 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7743 },
7744 {
7745 .vendor_id = QCA_NL80211_VENDOR_ID,
7746 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7747 },
7748 {
7749 .vendor_id = QCA_NL80211_VENDOR_ID,
7750 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7751 },
7752 {
7753 .vendor_id = QCA_NL80211_VENDOR_ID,
7754 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7755 },
7756 {
7757 .vendor_id = QCA_NL80211_VENDOR_ID,
7758 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7759 },
7760 {
7761 .vendor_id = QCA_NL80211_VENDOR_ID,
7762 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7763 },
7764 {
7765 .vendor_id = QCA_NL80211_VENDOR_ID,
7766 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7767 },
7768 {
7769 .vendor_id = QCA_NL80211_VENDOR_ID,
7770 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7771 },
7772 {
7773 .vendor_id = QCA_NL80211_VENDOR_ID,
7774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7775 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307776 {
7777 .vendor_id = QCA_NL80211_VENDOR_ID,
7778 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7779 },
7780 {
7781 .vendor_id = QCA_NL80211_VENDOR_ID,
7782 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7783 },
7784 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7785 .vendor_id = QCA_NL80211_VENDOR_ID,
7786 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7787 },
7788 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7789 .vendor_id = QCA_NL80211_VENDOR_ID,
7790 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7791 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307792#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307793/*EXT TDLS*/
7794 {
7795 .vendor_id = QCA_NL80211_VENDOR_ID,
7796 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7797 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307798 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7799 .vendor_id = QCA_NL80211_VENDOR_ID,
7800 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7801 },
7802
Srinivas Dasari030bad32015-02-18 23:23:54 +05307803
7804 {
7805 .vendor_id = QCA_NL80211_VENDOR_ID,
7806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7807 },
7808
Sushant Kaushik084f6592015-09-10 13:11:56 +05307809 {
7810 .vendor_id = QCA_NL80211_VENDOR_ID,
7811 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307812 },
7813 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7814 .vendor_id = QCA_NL80211_VENDOR_ID,
7815 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7816 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05307817 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
7818 .vendor_id = QCA_NL80211_VENDOR_ID,
7819 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
7820 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307821
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007822};
7823
Jeff Johnson295189b2012-06-20 16:38:30 -07007824/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307825 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307826 * This function is called by hdd_wlan_startup()
7827 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307828 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007829 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307830struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007831{
7832 struct wiphy *wiphy;
7833 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307834 /*
7835 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 */
7837 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7838
7839 if (!wiphy)
7840 {
7841 /* Print error and jump into err label and free the memory */
7842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7843 return NULL;
7844 }
7845
Sunil Duttc69bccb2014-05-26 21:30:20 +05307846
Jeff Johnson295189b2012-06-20 16:38:30 -07007847 return wiphy;
7848}
7849
7850/*
7851 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307852 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 * private ioctl to change the band value
7854 */
7855int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7856{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307857 int i, j;
7858 eNVChannelEnabledType channelEnabledState;
7859
Jeff Johnsone7245742012-09-05 17:12:55 -07007860 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307861
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307862 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307864
7865 if (NULL == wiphy->bands[i])
7866 {
7867 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7868 __func__, i);
7869 continue;
7870 }
7871
7872 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7873 {
7874 struct ieee80211_supported_band *band = wiphy->bands[i];
7875
7876 channelEnabledState = vos_nv_getChannelEnabledState(
7877 band->channels[j].hw_value);
7878
7879 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7880 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307881 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307882 continue;
7883 }
7884 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7885 {
7886 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7887 continue;
7888 }
7889
7890 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7891 NV_CHANNEL_INVALID == channelEnabledState)
7892 {
7893 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7894 }
7895 else if (NV_CHANNEL_DFS == channelEnabledState)
7896 {
7897 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7898 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7899 }
7900 else
7901 {
7902 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7903 |IEEE80211_CHAN_RADAR);
7904 }
7905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 }
7907 return 0;
7908}
7909/*
7910 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307911 * This function is called by hdd_wlan_startup()
7912 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 * This function is used to initialize and register wiphy structure.
7914 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307915int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 struct wiphy *wiphy,
7917 hdd_config_t *pCfg
7918 )
7919{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307920 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307921 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7922
Jeff Johnsone7245742012-09-05 17:12:55 -07007923 ENTER();
7924
Jeff Johnson295189b2012-06-20 16:38:30 -07007925 /* Now bind the underlying wlan device with wiphy */
7926 set_wiphy_dev(wiphy, dev);
7927
7928 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007929
Kiet Lam6c583332013-10-14 05:37:09 +05307930#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007931 /* the flag for the other case would be initialzed in
7932 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05307933#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7934 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
7935#else
Amar Singhal0a402232013-10-11 20:57:16 -07007936 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307937#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05307938#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007939
Amar Singhalfddc28c2013-09-05 13:03:40 -07007940 /* This will disable updating of NL channels from passive to
7941 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307942#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7943 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7944#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007945 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307946#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007947
Amar Singhala49cbc52013-10-08 18:37:44 -07007948
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007950 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7951 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7952 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007953 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05307955 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307956#else
7957 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7958#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007959#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007960
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007961#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007962 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007963#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007964 || pCfg->isFastRoamIniFeatureEnabled
7965#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007966#ifdef FEATURE_WLAN_ESE
7967 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007968#endif
7969 )
7970 {
7971 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7972 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007973#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007974#ifdef FEATURE_WLAN_TDLS
7975 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7976 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7977#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307978#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307979 if (pCfg->configPNOScanSupport)
7980 {
7981 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7982 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7983 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7984 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7985 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307986#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007987
Abhishek Singh10d85972015-04-17 10:27:23 +05307988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7989 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7990#endif
7991
Amar Singhalfddc28c2013-09-05 13:03:40 -07007992#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007993 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7994 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007995 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007996 driver need to determine what to do with both
7997 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007998
7999 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008000#else
8001 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008002#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008003
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308004 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8005
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308006 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008007
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308008 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8009
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308011 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8012 | BIT(NL80211_IFTYPE_ADHOC)
8013 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8014 | BIT(NL80211_IFTYPE_P2P_GO)
8015 | BIT(NL80211_IFTYPE_AP);
8016
8017 if (VOS_MONITOR_MODE == hdd_get_conparam())
8018 {
8019 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
8020 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008021
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308022 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008023 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8025 if( pCfg->enableMCC )
8026 {
8027 /* Currently, supports up to two channels */
8028 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008029
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308030 if( !pCfg->allowMCCGODiffBI )
8031 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008032
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308033 }
8034 wiphy->iface_combinations = &wlan_hdd_iface_combination;
8035 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008036#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308037 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008038
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 /* Before registering we need to update the ht capabilitied based
8040 * on ini values*/
8041 if( !pCfg->ShortGI20MhzEnable )
8042 {
8043 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8044 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 }
8046
8047 if( !pCfg->ShortGI40MhzEnable )
8048 {
8049 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
8050 }
8051
8052 if( !pCfg->nChannelBondingMode5GHz )
8053 {
8054 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8055 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05308056 /*
8057 * In case of static linked driver at the time of driver unload,
8058 * module exit doesn't happens. Module cleanup helps in cleaning
8059 * of static memory.
8060 * If driver load happens statically, at the time of driver unload,
8061 * wiphy flags don't get reset because of static memory.
8062 * It's better not to store channel in static memory.
8063 */
8064 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
8065 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
8066 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
8067 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
8068 {
8069 hddLog(VOS_TRACE_LEVEL_ERROR,
8070 FL("Not enough memory to allocate channels"));
8071 return -ENOMEM;
8072 }
8073 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
8074 &hdd_channels_2_4_GHZ[0],
8075 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07008076
Agrawal Ashish97dec502015-11-26 20:20:58 +05308077 if (true == hdd_is_5g_supported(pHddCtx))
8078 {
8079 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
8080 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
8081 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
8082 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
8083 {
8084 hddLog(VOS_TRACE_LEVEL_ERROR,
8085 FL("Not enough memory to allocate channels"));
8086 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
8087 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
8088 return -ENOMEM;
8089 }
8090 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
8091 &hdd_channels_5_GHZ[0],
8092 sizeof(hdd_channels_5_GHZ));
8093 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308094
8095 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8096 {
8097
8098 if (NULL == wiphy->bands[i])
8099 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308100 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308101 __func__, i);
8102 continue;
8103 }
8104
8105 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8106 {
8107 struct ieee80211_supported_band *band = wiphy->bands[i];
8108
8109 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8110 {
8111 // Enable social channels for P2P
8112 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8113 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8114 else
8115 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8116 continue;
8117 }
8118 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8119 {
8120 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8121 continue;
8122 }
8123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008124 }
8125 /*Initialise the supported cipher suite details*/
8126 wiphy->cipher_suites = hdd_cipher_suites;
8127 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8128
8129 /*signal strength in mBm (100*dBm) */
8130 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8131
8132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308133 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008134#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008135
Sunil Duttc69bccb2014-05-26 21:30:20 +05308136 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8137 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008138 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8139 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8140
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308141 EXIT();
8142 return 0;
8143}
8144
8145/* In this function we are registering wiphy. */
8146int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8147{
8148 ENTER();
8149 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 if (0 > wiphy_register(wiphy))
8151 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308152 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8154 return -EIO;
8155 }
8156
8157 EXIT();
8158 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308159}
Jeff Johnson295189b2012-06-20 16:38:30 -07008160
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308161/* In this function we are updating channel list when,
8162 regulatory domain is FCC and country code is US.
8163 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8164 As per FCC smart phone is not a indoor device.
8165 GO should not opeate on indoor channels */
8166void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8167{
8168 int j;
8169 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8170 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8171 //Default counrtycode from NV at the time of wiphy initialization.
8172 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8173 &defaultCountryCode[0]))
8174 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008175 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308176 }
8177 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8178 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308179 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8180 {
8181 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8182 return;
8183 }
8184 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8185 {
8186 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8187 // Mark UNII -1 band channel as passive
8188 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8189 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8190 }
8191 }
8192}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308193/* This function registers for all frame which supplicant is interested in */
8194void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008195{
Jeff Johnson295189b2012-06-20 16:38:30 -07008196 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8197 /* Register for all P2P action, public action etc frames */
8198 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07008199 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05308200 /* Register frame indication call back */
8201 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07008202 /* Right now we are registering these frame when driver is getting
8203 initialized. Once we will move to 2.6.37 kernel, in which we have
8204 frame register ops, we will move this code as a part of that */
8205 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308206 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8208
8209 /* GAS Initial Response */
8210 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8211 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308212
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 /* GAS Comeback Request */
8214 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8215 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8216
8217 /* GAS Comeback Response */
8218 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8219 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8220
8221 /* P2P Public Action */
8222 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308223 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 P2P_PUBLIC_ACTION_FRAME_SIZE );
8225
8226 /* P2P Action */
8227 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8228 (v_U8_t*)P2P_ACTION_FRAME,
8229 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008230
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308231 /* WNM BSS Transition Request frame */
8232 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8233 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8234 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008235
8236 /* WNM-Notification */
8237 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8238 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8239 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008240}
8241
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308242void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008243{
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8245 /* Register for all P2P action, public action etc frames */
8246 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8247
Jeff Johnsone7245742012-09-05 17:12:55 -07008248 ENTER();
8249
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 /* Right now we are registering these frame when driver is getting
8251 initialized. Once we will move to 2.6.37 kernel, in which we have
8252 frame register ops, we will move this code as a part of that */
8253 /* GAS Initial Request */
8254
8255 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8256 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8257
8258 /* GAS Initial Response */
8259 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8260 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308261
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 /* GAS Comeback Request */
8263 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8264 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8265
8266 /* GAS Comeback Response */
8267 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8268 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8269
8270 /* P2P Public Action */
8271 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308272 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 P2P_PUBLIC_ACTION_FRAME_SIZE );
8274
8275 /* P2P Action */
8276 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8277 (v_U8_t*)P2P_ACTION_FRAME,
8278 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008279 /* WNM-Notification */
8280 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8281 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8282 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008283}
8284
8285#ifdef FEATURE_WLAN_WAPI
8286void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308287 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008288{
8289 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8290 tCsrRoamSetKey setKey;
8291 v_BOOL_t isConnected = TRUE;
8292 int status = 0;
8293 v_U32_t roamId= 0xFF;
8294 tANI_U8 *pKeyPtr = NULL;
8295 int n = 0;
8296
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308297 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8298 __func__, hdd_device_modetoString(pAdapter->device_mode),
8299 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008300
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308301 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 setKey.keyId = key_index; // Store Key ID
8303 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8304 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8305 setKey.paeRole = 0 ; // the PAE role
8306 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8307 {
8308 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8309 }
8310 else
8311 {
8312 isConnected = hdd_connIsConnected(pHddStaCtx);
8313 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8314 }
8315 setKey.keyLength = key_Len;
8316 pKeyPtr = setKey.Key;
8317 memcpy( pKeyPtr, key, key_Len);
8318
Arif Hussain6d2a3322013-11-17 19:50:10 -08008319 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008320 __func__, key_Len);
8321 for (n = 0 ; n < key_Len; n++)
8322 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8323 __func__,n,setKey.Key[n]);
8324
8325 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8326 if ( isConnected )
8327 {
8328 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8329 pAdapter->sessionId, &setKey, &roamId );
8330 }
8331 if ( status != 0 )
8332 {
8333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8334 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8335 __LINE__, status );
8336 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8337 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308338 /* Need to clear any trace of key value in the memory.
8339 * Thus zero out the memory even though it is local
8340 * variable.
8341 */
8342 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008343}
8344#endif /* FEATURE_WLAN_WAPI*/
8345
8346#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308347int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008348 beacon_data_t **ppBeacon,
8349 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008350#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308351int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008352 beacon_data_t **ppBeacon,
8353 struct cfg80211_beacon_data *params,
8354 int dtim_period)
8355#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308356{
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 int size;
8358 beacon_data_t *beacon = NULL;
8359 beacon_data_t *old = NULL;
8360 int head_len,tail_len;
8361
Jeff Johnsone7245742012-09-05 17:12:55 -07008362 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308364 {
8365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8366 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008369
8370 old = pAdapter->sessionCtx.ap.beacon;
8371
8372 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308373 {
8374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8375 FL("session(%d) old and new heads points to NULL"),
8376 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008377 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308378 }
8379
8380 if (params->tail && !params->tail_len)
8381 {
8382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8383 FL("tail_len is zero but tail is not NULL"));
8384 return -EINVAL;
8385 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8388 /* Kernel 3.0 is not updating dtim_period for set beacon */
8389 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308390 {
8391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8392 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308394 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008395#endif
8396
8397 if(params->head)
8398 head_len = params->head_len;
8399 else
8400 head_len = old->head_len;
8401
8402 if(params->tail || !old)
8403 tail_len = params->tail_len;
8404 else
8405 tail_len = old->tail_len;
8406
8407 size = sizeof(beacon_data_t) + head_len + tail_len;
8408
8409 beacon = kzalloc(size, GFP_KERNEL);
8410
8411 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308412 {
8413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8414 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308416 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008417
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008418#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 if(params->dtim_period || !old )
8420 beacon->dtim_period = params->dtim_period;
8421 else
8422 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008423#else
8424 if(dtim_period || !old )
8425 beacon->dtim_period = dtim_period;
8426 else
8427 beacon->dtim_period = old->dtim_period;
8428#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308429
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8431 beacon->tail = beacon->head + head_len;
8432 beacon->head_len = head_len;
8433 beacon->tail_len = tail_len;
8434
8435 if(params->head) {
8436 memcpy (beacon->head,params->head,beacon->head_len);
8437 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308438 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 if(old)
8440 memcpy (beacon->head,old->head,beacon->head_len);
8441 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308442
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 if(params->tail) {
8444 memcpy (beacon->tail,params->tail,beacon->tail_len);
8445 }
8446 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308447 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 memcpy (beacon->tail,old->tail,beacon->tail_len);
8449 }
8450
8451 *ppBeacon = beacon;
8452
8453 kfree(old);
8454
8455 return 0;
8456
8457}
Jeff Johnson295189b2012-06-20 16:38:30 -07008458
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308459v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8460#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8461 const v_U8_t *pIes,
8462#else
8463 v_U8_t *pIes,
8464#endif
8465 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008466{
8467 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308468 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308470
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308472 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 elem_id = ptr[0];
8474 elem_len = ptr[1];
8475 left -= 2;
8476 if(elem_len > left)
8477 {
8478 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008479 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 eid,elem_len,left);
8481 return NULL;
8482 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308483 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 {
8485 return ptr;
8486 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308487
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 left -= elem_len;
8489 ptr += (elem_len + 2);
8490 }
8491 return NULL;
8492}
8493
Jeff Johnson295189b2012-06-20 16:38:30 -07008494/* Check if rate is 11g rate or not */
8495static int wlan_hdd_rate_is_11g(u8 rate)
8496{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008497 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008498 u8 i;
8499 for (i = 0; i < 8; i++)
8500 {
8501 if(rate == gRateArray[i])
8502 return TRUE;
8503 }
8504 return FALSE;
8505}
8506
8507/* Check for 11g rate and set proper 11g only mode */
8508static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8509 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8510{
8511 u8 i, num_rates = pIe[0];
8512
8513 pIe += 1;
8514 for ( i = 0; i < num_rates; i++)
8515 {
8516 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8517 {
8518 /* If rate set have 11g rate than change the mode to 11G */
8519 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8520 if (pIe[i] & BASIC_RATE_MASK)
8521 {
8522 /* If we have 11g rate as basic rate, it means mode
8523 is 11g only mode.
8524 */
8525 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8526 *pCheckRatesfor11g = FALSE;
8527 }
8528 }
8529 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8530 {
8531 *require_ht = TRUE;
8532 }
8533 }
8534 return;
8535}
8536
8537static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8538{
8539 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8540 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8541 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8542 u8 checkRatesfor11g = TRUE;
8543 u8 require_ht = FALSE;
8544 u8 *pIe=NULL;
8545
8546 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8547
8548 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8549 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8550 if (pIe != NULL)
8551 {
8552 pIe += 1;
8553 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8554 &pConfig->SapHw_mode);
8555 }
8556
8557 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8558 WLAN_EID_EXT_SUPP_RATES);
8559 if (pIe != NULL)
8560 {
8561
8562 pIe += 1;
8563 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8564 &pConfig->SapHw_mode);
8565 }
8566
8567 if( pConfig->channel > 14 )
8568 {
8569 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8570 }
8571
8572 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8573 WLAN_EID_HT_CAPABILITY);
8574
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308575 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008576 {
8577 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8578 if(require_ht)
8579 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8580 }
8581}
8582
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308583static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8584 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8585{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008586 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308587 v_U8_t *pIe = NULL;
8588 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8589
8590 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8591 pBeacon->tail, pBeacon->tail_len);
8592
8593 if (pIe)
8594 {
8595 ielen = pIe[1] + 2;
8596 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8597 {
8598 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8599 }
8600 else
8601 {
8602 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8603 return -EINVAL;
8604 }
8605 *total_ielen += ielen;
8606 }
8607 return 0;
8608}
8609
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008610static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8611 v_U8_t *genie, v_U8_t *total_ielen)
8612{
8613 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8614 int left = pBeacon->tail_len;
8615 v_U8_t *ptr = pBeacon->tail;
8616 v_U8_t elem_id, elem_len;
8617 v_U16_t ielen = 0;
8618
8619 if ( NULL == ptr || 0 == left )
8620 return;
8621
8622 while (left >= 2)
8623 {
8624 elem_id = ptr[0];
8625 elem_len = ptr[1];
8626 left -= 2;
8627 if (elem_len > left)
8628 {
8629 hddLog( VOS_TRACE_LEVEL_ERROR,
8630 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8631 elem_id, elem_len, left);
8632 return;
8633 }
8634 if (IE_EID_VENDOR == elem_id)
8635 {
8636 /* skipping the VSIE's which we don't want to include or
8637 * it will be included by existing code
8638 */
8639 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8640#ifdef WLAN_FEATURE_WFD
8641 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8642#endif
8643 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8644 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8645 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8646 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8647 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8648 {
8649 ielen = ptr[1] + 2;
8650 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8651 {
8652 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8653 *total_ielen += ielen;
8654 }
8655 else
8656 {
8657 hddLog( VOS_TRACE_LEVEL_ERROR,
8658 "IE Length is too big "
8659 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8660 elem_id, elem_len, *total_ielen);
8661 }
8662 }
8663 }
8664
8665 left -= elem_len;
8666 ptr += (elem_len + 2);
8667 }
8668 return;
8669}
8670
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008671#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008672static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8673 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008674#else
8675static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8676 struct cfg80211_beacon_data *params)
8677#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008678{
8679 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308680 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008681 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008682 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008683
8684 genie = vos_mem_malloc(MAX_GENIE_LEN);
8685
8686 if(genie == NULL) {
8687
8688 return -ENOMEM;
8689 }
8690
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308691 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8692 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008693 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308694 hddLog(LOGE,
8695 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308696 ret = -EINVAL;
8697 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 }
8699
8700#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308701 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8702 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8703 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308704 hddLog(LOGE,
8705 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308706 ret = -EINVAL;
8707 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 }
8709#endif
8710
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308711 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8712 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308714 hddLog(LOGE,
8715 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308716 ret = -EINVAL;
8717 goto done;
8718 }
8719
8720 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8721 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008722 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008724
8725 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8726 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8727 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8728 {
8729 hddLog(LOGE,
8730 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008731 ret = -EINVAL;
8732 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 }
8734
8735 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8736 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8737 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8738 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8739 ==eHAL_STATUS_FAILURE)
8740 {
8741 hddLog(LOGE,
8742 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008743 ret = -EINVAL;
8744 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 }
8746
8747 // Added for ProResp IE
8748 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8749 {
8750 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8751 u8 probe_rsp_ie_len[3] = {0};
8752 u8 counter = 0;
8753 /* Check Probe Resp Length if it is greater then 255 then Store
8754 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8755 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8756 Store More then 255 bytes into One Variable.
8757 */
8758 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8759 {
8760 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8761 {
8762 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8763 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8764 }
8765 else
8766 {
8767 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8768 rem_probe_resp_ie_len = 0;
8769 }
8770 }
8771
8772 rem_probe_resp_ie_len = 0;
8773
8774 if (probe_rsp_ie_len[0] > 0)
8775 {
8776 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8777 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8778 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8779 probe_rsp_ie_len[0], NULL,
8780 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8781 {
8782 hddLog(LOGE,
8783 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008784 ret = -EINVAL;
8785 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 }
8787 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8788 }
8789
8790 if (probe_rsp_ie_len[1] > 0)
8791 {
8792 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8793 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8794 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8795 probe_rsp_ie_len[1], NULL,
8796 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8797 {
8798 hddLog(LOGE,
8799 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008800 ret = -EINVAL;
8801 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 }
8803 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8804 }
8805
8806 if (probe_rsp_ie_len[2] > 0)
8807 {
8808 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8809 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8810 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8811 probe_rsp_ie_len[2], NULL,
8812 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8813 {
8814 hddLog(LOGE,
8815 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008816 ret = -EINVAL;
8817 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008818 }
8819 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8820 }
8821
8822 if (probe_rsp_ie_len[1] == 0 )
8823 {
8824 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8825 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8826 eANI_BOOLEAN_FALSE) )
8827 {
8828 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008829 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008830 }
8831 }
8832
8833 if (probe_rsp_ie_len[2] == 0 )
8834 {
8835 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8836 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8837 eANI_BOOLEAN_FALSE) )
8838 {
8839 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008840 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 }
8842 }
8843
8844 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8845 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8846 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8847 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8848 == eHAL_STATUS_FAILURE)
8849 {
8850 hddLog(LOGE,
8851 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008852 ret = -EINVAL;
8853 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 }
8855 }
8856 else
8857 {
8858 // Reset WNI_CFG_PROBE_RSP Flags
8859 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8860
8861 hddLog(VOS_TRACE_LEVEL_INFO,
8862 "%s: No Probe Response IE received in set beacon",
8863 __func__);
8864 }
8865
8866 // Added for AssocResp IE
8867 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8868 {
8869 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8870 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8871 params->assocresp_ies_len, NULL,
8872 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8873 {
8874 hddLog(LOGE,
8875 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008876 ret = -EINVAL;
8877 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 }
8879
8880 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8881 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8882 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8883 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8884 == eHAL_STATUS_FAILURE)
8885 {
8886 hddLog(LOGE,
8887 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008888 ret = -EINVAL;
8889 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 }
8891 }
8892 else
8893 {
8894 hddLog(VOS_TRACE_LEVEL_INFO,
8895 "%s: No Assoc Response IE received in set beacon",
8896 __func__);
8897
8898 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8899 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8900 eANI_BOOLEAN_FALSE) )
8901 {
8902 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008903 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 }
8905 }
8906
Jeff Johnsone7245742012-09-05 17:12:55 -07008907done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308909 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008910}
Jeff Johnson295189b2012-06-20 16:38:30 -07008911
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308912/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 * FUNCTION: wlan_hdd_validate_operation_channel
8914 * called by wlan_hdd_cfg80211_start_bss() and
8915 * wlan_hdd_cfg80211_set_channel()
8916 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308917 * channel list.
8918 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008919VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008920{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308921
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 v_U32_t num_ch = 0;
8923 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8924 u32 indx = 0;
8925 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308926 v_U8_t fValidChannel = FALSE, count = 0;
8927 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308928
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8930
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308931 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308933 /* Validate the channel */
8934 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308936 if ( channel == rfChannels[count].channelNum )
8937 {
8938 fValidChannel = TRUE;
8939 break;
8940 }
8941 }
8942 if (fValidChannel != TRUE)
8943 {
8944 hddLog(VOS_TRACE_LEVEL_ERROR,
8945 "%s: Invalid Channel [%d]", __func__, channel);
8946 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 }
8948 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308949 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308951 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8952 valid_ch, &num_ch))
8953 {
8954 hddLog(VOS_TRACE_LEVEL_ERROR,
8955 "%s: failed to get valid channel list", __func__);
8956 return VOS_STATUS_E_FAILURE;
8957 }
8958 for (indx = 0; indx < num_ch; indx++)
8959 {
8960 if (channel == valid_ch[indx])
8961 {
8962 break;
8963 }
8964 }
8965
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308966 if (indx >= num_ch)
8967 {
8968 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8969 {
8970 eCsrBand band;
8971 unsigned int freq;
8972
8973 sme_GetFreqBand(hHal, &band);
8974
8975 if (eCSR_BAND_5G == band)
8976 {
8977#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8978 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8979 {
8980 freq = ieee80211_channel_to_frequency(channel,
8981 IEEE80211_BAND_2GHZ);
8982 }
8983 else
8984 {
8985 freq = ieee80211_channel_to_frequency(channel,
8986 IEEE80211_BAND_5GHZ);
8987 }
8988#else
8989 freq = ieee80211_channel_to_frequency(channel);
8990#endif
8991 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8992 return VOS_STATUS_SUCCESS;
8993 }
8994 }
8995
8996 hddLog(VOS_TRACE_LEVEL_ERROR,
8997 "%s: Invalid Channel [%d]", __func__, channel);
8998 return VOS_STATUS_E_FAILURE;
8999 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309001
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309003
Jeff Johnson295189b2012-06-20 16:38:30 -07009004}
9005
Viral Modi3a32cc52013-02-08 11:14:52 -08009006/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309007 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009008 * This function is used to set the channel number
9009 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309010static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009011 struct ieee80211_channel *chan,
9012 enum nl80211_channel_type channel_type
9013 )
9014{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309015 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009016 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009017 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009018 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309019 hdd_context_t *pHddCtx;
9020 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009021
9022 ENTER();
9023
9024 if( NULL == dev )
9025 {
9026 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009027 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009028 return -ENODEV;
9029 }
9030 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309031
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309032 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9033 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
9034 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08009035 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309036 "%s: device_mode = %s (%d) freq = %d", __func__,
9037 hdd_device_modetoString(pAdapter->device_mode),
9038 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309039
9040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9041 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309042 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08009043 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309044 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009045 }
9046
9047 /*
9048 * Do freq to chan conversion
9049 * TODO: for 11a
9050 */
9051
9052 channel = ieee80211_frequency_to_channel(freq);
9053
9054 /* Check freq range */
9055 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
9056 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
9057 {
9058 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009059 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08009060 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
9061 WNI_CFG_CURRENT_CHANNEL_STAMAX);
9062 return -EINVAL;
9063 }
9064
9065 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9066
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05309067 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
9068 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08009069 {
9070 if(VOS_STATUS_SUCCESS != 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);
Viral Modi3a32cc52013-02-08 11:14:52 -08009074 return -EINVAL;
9075 }
9076 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9077 "%s: set channel to [%d] for device mode =%d",
9078 __func__, channel,pAdapter->device_mode);
9079 }
9080 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08009081 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08009082 )
9083 {
9084 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9085 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
9086 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9087
9088 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
9089 {
9090 /* Link is up then return cant set channel*/
9091 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009092 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08009093 return -EINVAL;
9094 }
9095
9096 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9097 pHddStaCtx->conn_info.operationChannel = channel;
9098 pRoamProfile->ChannelInfo.ChannelList =
9099 &pHddStaCtx->conn_info.operationChannel;
9100 }
9101 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009102 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009103 )
9104 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309105 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9106 {
9107 if(VOS_STATUS_SUCCESS !=
9108 wlan_hdd_validate_operation_channel(pAdapter,channel))
9109 {
9110 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009111 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309112 return -EINVAL;
9113 }
9114 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9115 }
9116 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009117 {
9118 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9119
9120 /* If auto channel selection is configured as enable/ 1 then ignore
9121 channel set by supplicant
9122 */
9123 if ( cfg_param->apAutoChannelSelection )
9124 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309125 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9126 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009127 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309128 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9129 __func__, hdd_device_modetoString(pAdapter->device_mode),
9130 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009131 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309132 else
9133 {
9134 if(VOS_STATUS_SUCCESS !=
9135 wlan_hdd_validate_operation_channel(pAdapter,channel))
9136 {
9137 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009138 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309139 return -EINVAL;
9140 }
9141 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9142 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009143 }
9144 }
9145 else
9146 {
9147 hddLog(VOS_TRACE_LEVEL_FATAL,
9148 "%s: Invalid device mode failed to set valid channel", __func__);
9149 return -EINVAL;
9150 }
9151 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309152 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009153}
9154
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309155static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9156 struct net_device *dev,
9157 struct ieee80211_channel *chan,
9158 enum nl80211_channel_type channel_type
9159 )
9160{
9161 int ret;
9162
9163 vos_ssr_protect(__func__);
9164 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9165 vos_ssr_unprotect(__func__);
9166
9167 return ret;
9168}
9169
Jeff Johnson295189b2012-06-20 16:38:30 -07009170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9171static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9172 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009173#else
9174static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9175 struct cfg80211_beacon_data *params,
9176 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309177 enum nl80211_hidden_ssid hidden_ssid,
9178 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009179#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009180{
9181 tsap_Config_t *pConfig;
9182 beacon_data_t *pBeacon = NULL;
9183 struct ieee80211_mgmt *pMgmt_frame;
9184 v_U8_t *pIe=NULL;
9185 v_U16_t capab_info;
9186 eCsrAuthType RSNAuthType;
9187 eCsrEncryptionType RSNEncryptType;
9188 eCsrEncryptionType mcRSNEncryptType;
9189 int status = VOS_STATUS_SUCCESS;
9190 tpWLAN_SAPEventCB pSapEventCallback;
9191 hdd_hostapd_state_t *pHostapdState;
9192 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9193 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309194 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009195 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309196 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009197 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009198 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309199 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009200 v_BOOL_t MFPCapable = VOS_FALSE;
9201 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309202 v_BOOL_t sapEnable11AC =
9203 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 ENTER();
9205
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309206 iniConfig = pHddCtx->cfg_ini;
9207
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9209
9210 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9211
9212 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9213
9214 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9215
9216 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9217
9218 //channel is already set in the set_channel Call back
9219 //pConfig->channel = pCommitConfig->channel;
9220
9221 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309222 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9224
9225 pConfig->dtim_period = pBeacon->dtim_period;
9226
Arif Hussain6d2a3322013-11-17 19:50:10 -08009227 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 pConfig->dtim_period);
9229
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009230 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009231 {
9232 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309234 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9235 {
9236 tANI_BOOLEAN restartNeeded;
9237 pConfig->ieee80211d = 1;
9238 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9239 sme_setRegInfo(hHal, pConfig->countryCode);
9240 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9241 }
9242 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009244 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009245 pConfig->ieee80211d = 1;
9246 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9247 sme_setRegInfo(hHal, pConfig->countryCode);
9248 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009249 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009250 else
9251 {
9252 pConfig->ieee80211d = 0;
9253 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309254 /*
9255 * If auto channel is configured i.e. channel is 0,
9256 * so skip channel validation.
9257 */
9258 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9259 {
9260 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9261 {
9262 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009263 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309264 return -EINVAL;
9265 }
9266 }
9267 else
9268 {
9269 if(1 != pHddCtx->is_dynamic_channel_range_set)
9270 {
9271 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9272 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9273 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9274 }
9275 pHddCtx->is_dynamic_channel_range_set = 0;
9276 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009278 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 {
9280 pConfig->ieee80211d = 0;
9281 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309282
9283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9284 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9285 pConfig->authType = eSAP_OPEN_SYSTEM;
9286 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9287 pConfig->authType = eSAP_SHARED_KEY;
9288 else
9289 pConfig->authType = eSAP_AUTO_SWITCH;
9290#else
9291 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9292 pConfig->authType = eSAP_OPEN_SYSTEM;
9293 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9294 pConfig->authType = eSAP_SHARED_KEY;
9295 else
9296 pConfig->authType = eSAP_AUTO_SWITCH;
9297#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009298
9299 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309300
9301 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9303
9304 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9305
9306 /*Set wps station to configured*/
9307 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9308
9309 if(pIe)
9310 {
9311 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9312 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009313 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 return -EINVAL;
9315 }
9316 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9317 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009318 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 /* Check 15 bit of WPS IE as it contain information for wps state
9320 * WPS state
9321 */
9322 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9323 {
9324 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9325 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9326 {
9327 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9328 }
9329 }
9330 }
9331 else
9332 {
9333 pConfig->wps_state = SAP_WPS_DISABLED;
9334 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309335 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009336
c_hpothufe599e92014-06-16 11:38:55 +05309337 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9338 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9339 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9340 eCSR_ENCRYPT_TYPE_NONE;
9341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 pConfig->RSNWPAReqIELength = 0;
9343 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 WLAN_EID_RSN);
9346 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9349 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9350 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309351 /* The actual processing may eventually be more extensive than
9352 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 * by the app.
9354 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9357 &RSNEncryptType,
9358 &mcRSNEncryptType,
9359 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009360 &MFPCapable,
9361 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 pConfig->pRSNWPAReqIE[1]+2,
9363 pConfig->pRSNWPAReqIE );
9364
9365 if( VOS_STATUS_SUCCESS == status )
9366 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309367 /* Now copy over all the security attributes you have
9368 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 * */
9370 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9371 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9372 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9373 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309374 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009375 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9377 }
9378 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9381 pBeacon->tail, pBeacon->tail_len);
9382
9383 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9384 {
9385 if (pConfig->pRSNWPAReqIE)
9386 {
9387 /*Mixed mode WPA/WPA2*/
9388 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9389 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9390 }
9391 else
9392 {
9393 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9394 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9395 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309396 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9398 &RSNEncryptType,
9399 &mcRSNEncryptType,
9400 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009401 &MFPCapable,
9402 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 pConfig->pRSNWPAReqIE[1]+2,
9404 pConfig->pRSNWPAReqIE );
9405
9406 if( VOS_STATUS_SUCCESS == status )
9407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309408 /* Now copy over all the security attributes you have
9409 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 * */
9411 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9412 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9413 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9414 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309415 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009416 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9418 }
9419 }
9420 }
9421
Jeff Johnson4416a782013-03-25 14:17:50 -07009422 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9423 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9424 return -EINVAL;
9425 }
9426
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9428
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009429#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 if (params->ssid != NULL)
9431 {
9432 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9433 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9434 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9435 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9436 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009437#else
9438 if (ssid != NULL)
9439 {
9440 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9441 pConfig->SSIDinfo.ssid.length = ssid_len;
9442 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9443 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9444 }
9445#endif
9446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309449
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 /* default value */
9451 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9452 pConfig->num_accept_mac = 0;
9453 pConfig->num_deny_mac = 0;
9454
9455 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9456 pBeacon->tail, pBeacon->tail_len);
9457
9458 /* pIe for black list is following form:
9459 type : 1 byte
9460 length : 1 byte
9461 OUI : 4 bytes
9462 acl type : 1 byte
9463 no of mac addr in black list: 1 byte
9464 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309465 */
9466 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 {
9468 pConfig->SapMacaddr_acl = pIe[6];
9469 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009470 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309472 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9473 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9475 for (i = 0; i < pConfig->num_deny_mac; i++)
9476 {
9477 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9478 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 }
9481 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9482 pBeacon->tail, pBeacon->tail_len);
9483
9484 /* pIe for white list is following form:
9485 type : 1 byte
9486 length : 1 byte
9487 OUI : 4 bytes
9488 acl type : 1 byte
9489 no of mac addr in white list: 1 byte
9490 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309491 */
9492 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 {
9494 pConfig->SapMacaddr_acl = pIe[6];
9495 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009496 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009497 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309498 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9499 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9501 for (i = 0; i < pConfig->num_accept_mac; i++)
9502 {
9503 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9504 acl_entry++;
9505 }
9506 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309507
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9509
Jeff Johnsone7245742012-09-05 17:12:55 -07009510#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009511 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309512 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9513 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309514 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9515 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009516 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9517 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309518 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9519 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009520 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309521 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009522 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309523 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009524
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309525 /* If ACS disable and selected channel <= 14
9526 * OR
9527 * ACS enabled and ACS operating band is choosen as 2.4
9528 * AND
9529 * VHT in 2.4G Disabled
9530 * THEN
9531 * Fallback to 11N mode
9532 */
9533 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9534 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309535 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309536 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009537 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309538 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9539 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009540 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9541 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009542 }
9543#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309544
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 // ht_capab is not what the name conveys,this is used for protection bitmap
9546 pConfig->ht_capab =
9547 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9548
9549 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9550 {
9551 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9552 return -EINVAL;
9553 }
9554
9555 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309556 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9558 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309559 pConfig->obssProtEnabled =
9560 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009561
Chet Lanctot8cecea22014-02-11 19:09:36 -08009562#ifdef WLAN_FEATURE_11W
9563 pConfig->mfpCapable = MFPCapable;
9564 pConfig->mfpRequired = MFPRequired;
9565 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9566 pConfig->mfpCapable, pConfig->mfpRequired);
9567#endif
9568
Arif Hussain6d2a3322013-11-17 19:50:10 -08009569 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009571 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9572 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9573 (int)pConfig->channel);
9574 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9575 pConfig->SapHw_mode, pConfig->privacy,
9576 pConfig->authType);
9577 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9578 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9579 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9580 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009581
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309582 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 {
9584 //Bss already started. just return.
9585 //TODO Probably it should update some beacon params.
9586 hddLog( LOGE, "Bss Already started...Ignore the request");
9587 EXIT();
9588 return 0;
9589 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309590
Agarwal Ashish51325b52014-06-16 16:50:49 +05309591 if (vos_max_concurrent_connections_reached()) {
9592 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9593 return -EINVAL;
9594 }
9595
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 pConfig->persona = pHostapdAdapter->device_mode;
9597
Peng Xu2446a892014-09-05 17:21:18 +05309598 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9599 if ( NULL != psmeConfig)
9600 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309601 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309602 sme_GetConfigParam(hHal, psmeConfig);
9603 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309604#ifdef WLAN_FEATURE_AP_HT40_24G
9605 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9606 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9607 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9608 {
9609 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9610 sme_UpdateConfig (hHal, psmeConfig);
9611 }
9612#endif
Peng Xu2446a892014-09-05 17:21:18 +05309613 vos_mem_free(psmeConfig);
9614 }
Peng Xuafc34e32014-09-25 13:23:55 +05309615 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309616
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 pSapEventCallback = hdd_hostapd_SAPEventCB;
9618 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9619 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9620 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009621 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 return -EINVAL;
9623 }
9624
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309625 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9627
9628 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309629
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309631 {
9632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009633 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009634 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 VOS_ASSERT(0);
9636 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309637
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309639 /* Initialize WMM configuation */
9640 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309641 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009642
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009643#ifdef WLAN_FEATURE_P2P_DEBUG
9644 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9645 {
9646 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9647 {
9648 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9649 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009650 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009651 }
9652 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9653 {
9654 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9655 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009656 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009657 }
9658 }
9659#endif
9660
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 pHostapdState->bCommit = TRUE;
9662 EXIT();
9663
9664 return 0;
9665}
9666
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009667#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309668static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309669 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 struct beacon_parameters *params)
9671{
9672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309673 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309674 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009675
9676 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309677
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309678 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9679 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9680 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309681 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9682 hdd_device_modetoString(pAdapter->device_mode),
9683 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009684
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309685 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9686 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309687 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009688 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309689 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009690 }
9691
Agarwal Ashish51325b52014-06-16 16:50:49 +05309692 if (vos_max_concurrent_connections_reached()) {
9693 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9694 return -EINVAL;
9695 }
9696
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309697 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 )
9700 {
9701 beacon_data_t *old,*new;
9702
9703 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309704
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309706 {
9707 hddLog(VOS_TRACE_LEVEL_WARN,
9708 FL("already beacon info added to session(%d)"),
9709 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309711 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009712
9713 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9714
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309715 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 {
9717 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009718 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009719 return -EINVAL;
9720 }
9721
9722 pAdapter->sessionCtx.ap.beacon = new;
9723
9724 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9725 }
9726
9727 EXIT();
9728 return status;
9729}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309731static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9732 struct net_device *dev,
9733 struct beacon_parameters *params)
9734{
9735 int ret;
9736
9737 vos_ssr_protect(__func__);
9738 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9739 vos_ssr_unprotect(__func__);
9740
9741 return ret;
9742}
9743
9744static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 struct net_device *dev,
9746 struct beacon_parameters *params)
9747{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309749 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9750 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309751 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009752
9753 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309754
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309755 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9756 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9757 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9758 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9759 __func__, hdd_device_modetoString(pAdapter->device_mode),
9760 pAdapter->device_mode);
9761
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309762 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9763 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309764 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009765 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309766 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009767 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309768
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309769 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309771 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 {
9773 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309774
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309776
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309778 {
9779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9780 FL("session(%d) old and new heads points to NULL"),
9781 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309783 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009784
9785 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9786
9787 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309788 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009789 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 return -EINVAL;
9791 }
9792
9793 pAdapter->sessionCtx.ap.beacon = new;
9794
9795 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9796 }
9797
9798 EXIT();
9799 return status;
9800}
9801
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309802static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9803 struct net_device *dev,
9804 struct beacon_parameters *params)
9805{
9806 int ret;
9807
9808 vos_ssr_protect(__func__);
9809 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9810 vos_ssr_unprotect(__func__);
9811
9812 return ret;
9813}
9814
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009815#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9816
9817#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309818static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009820#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309821static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009822 struct net_device *dev)
9823#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009824{
9825 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009826 hdd_context_t *pHddCtx = NULL;
9827 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309828 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309829 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009830
9831 ENTER();
9832
9833 if (NULL == pAdapter)
9834 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009836 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 return -ENODEV;
9838 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009839
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309840 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9841 TRACE_CODE_HDD_CFG80211_STOP_AP,
9842 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309843 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9844 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309845 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009846 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309847 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009848 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009849
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009850 pScanInfo = &pHddCtx->scan_info;
9851
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309852 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9853 __func__, hdd_device_modetoString(pAdapter->device_mode),
9854 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009855
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309856 ret = wlan_hdd_scan_abort(pAdapter);
9857
Girish Gowli4bf7a632014-06-12 13:42:11 +05309858 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009859 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9861 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309862
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309863 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009864 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9866 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009867
Jeff Johnsone7245742012-09-05 17:12:55 -07009868 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309869 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009870 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309871 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009872 }
9873
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309874 /* Delete all associated STAs before stopping AP/P2P GO */
9875 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309876 hdd_hostapd_stop(dev);
9877
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 )
9881 {
9882 beacon_data_t *old;
9883
9884 old = pAdapter->sessionCtx.ap.beacon;
9885
9886 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309887 {
9888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9889 FL("session(%d) beacon data points to NULL"),
9890 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009893
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009895
9896 mutex_lock(&pHddCtx->sap_lock);
9897 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9898 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009899 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 {
9901 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9902
9903 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9904
9905 if (!VOS_IS_STATUS_SUCCESS(status))
9906 {
9907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009908 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309910 }
9911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309913 /* BSS stopped, clear the active sessions for this device mode */
9914 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 }
9916 mutex_unlock(&pHddCtx->sap_lock);
9917
9918 if(status != VOS_STATUS_SUCCESS)
9919 {
9920 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009921 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 return -EINVAL;
9923 }
9924
Jeff Johnson4416a782013-03-25 14:17:50 -07009925 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9927 ==eHAL_STATUS_FAILURE)
9928 {
9929 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009930 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 }
9932
Jeff Johnson4416a782013-03-25 14:17:50 -07009933 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9935 eANI_BOOLEAN_FALSE) )
9936 {
9937 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009938 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009939 }
9940
9941 // Reset WNI_CFG_PROBE_RSP Flags
9942 wlan_hdd_reset_prob_rspies(pAdapter);
9943
9944 pAdapter->sessionCtx.ap.beacon = NULL;
9945 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009946#ifdef WLAN_FEATURE_P2P_DEBUG
9947 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9948 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9949 {
9950 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9951 "GO got removed");
9952 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9953 }
9954#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 }
9956 EXIT();
9957 return status;
9958}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009959
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309960#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9961static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9962 struct net_device *dev)
9963{
9964 int ret;
9965
9966 vos_ssr_protect(__func__);
9967 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9968 vos_ssr_unprotect(__func__);
9969
9970 return ret;
9971}
9972#else
9973static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9974 struct net_device *dev)
9975{
9976 int ret;
9977
9978 vos_ssr_protect(__func__);
9979 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9980 vos_ssr_unprotect(__func__);
9981
9982 return ret;
9983}
9984#endif
9985
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009986#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9987
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309988static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309989 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009990 struct cfg80211_ap_settings *params)
9991{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309992 hdd_adapter_t *pAdapter;
9993 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309994 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009995
9996 ENTER();
9997
Girish Gowlib143d7a2015-02-18 19:39:55 +05309998 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053010001 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010002 return -ENODEV;
10003 }
10004
10005 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10006 if (NULL == pAdapter)
10007 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010009 "%s: HDD adapter is Null", __func__);
10010 return -ENODEV;
10011 }
10012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010013 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10014 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
10015 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010016 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
10017 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010019 "%s: HDD adapter magic is invalid", __func__);
10020 return -ENODEV;
10021 }
10022
10023 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010024 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010025 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010026 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010027 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010028 }
10029
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010030 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
10031 __func__, hdd_device_modetoString(pAdapter->device_mode),
10032 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010033
10034 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010035 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010036 )
10037 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010038 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010039
10040 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010041
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010042 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010043 {
10044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10045 FL("already beacon info added to session(%d)"),
10046 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010047 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010048 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010049
Girish Gowlib143d7a2015-02-18 19:39:55 +053010050#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10051 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10052 &new,
10053 &params->beacon);
10054#else
10055 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
10056 &new,
10057 &params->beacon,
10058 params->dtim_period);
10059#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010060
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010061 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010062 {
10063 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053010064 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010065 return -EINVAL;
10066 }
10067 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080010068#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070010069 wlan_hdd_cfg80211_set_channel(wiphy, dev,
10070#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
10071 params->channel, params->channel_type);
10072#else
10073 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
10074#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080010075#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010076 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010077 params->ssid_len, params->hidden_ssid,
10078 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010079 }
10080
10081 EXIT();
10082 return status;
10083}
10084
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010085static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
10086 struct net_device *dev,
10087 struct cfg80211_ap_settings *params)
10088{
10089 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010090
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010091 vos_ssr_protect(__func__);
10092 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
10093 vos_ssr_unprotect(__func__);
10094
10095 return ret;
10096}
10097
10098static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010099 struct net_device *dev,
10100 struct cfg80211_beacon_data *params)
10101{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010103 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010104 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010105
10106 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010107
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10109 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10110 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010112 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010113
10114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10115 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010116 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010117 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010118 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010119 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010120
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010121 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010122 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010123 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010124 {
10125 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010126
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010127 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010128
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010129 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010130 {
10131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10132 FL("session(%d) beacon data points to NULL"),
10133 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010134 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010135 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010136
10137 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10138
10139 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010140 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010141 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010142 return -EINVAL;
10143 }
10144
10145 pAdapter->sessionCtx.ap.beacon = new;
10146
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010147 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10148 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010149 }
10150
10151 EXIT();
10152 return status;
10153}
10154
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010155static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10156 struct net_device *dev,
10157 struct cfg80211_beacon_data *params)
10158{
10159 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010160
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010161 vos_ssr_protect(__func__);
10162 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10163 vos_ssr_unprotect(__func__);
10164
10165 return ret;
10166}
10167
10168#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010169
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010170static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 struct net_device *dev,
10172 struct bss_parameters *params)
10173{
10174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010175 hdd_context_t *pHddCtx;
10176 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010177
10178 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010179
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010180 if (NULL == pAdapter)
10181 {
10182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10183 "%s: HDD adapter is Null", __func__);
10184 return -ENODEV;
10185 }
10186 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010187 ret = wlan_hdd_validate_context(pHddCtx);
10188 if (0 != ret)
10189 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010190 return ret;
10191 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10193 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10194 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10196 __func__, hdd_device_modetoString(pAdapter->device_mode),
10197 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010198
10199 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010201 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 {
10203 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10204 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010205 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 {
10207 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010208 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 }
10210
10211 EXIT();
10212 return 0;
10213}
10214
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010215static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10216 struct net_device *dev,
10217 struct bss_parameters *params)
10218{
10219 int ret;
10220
10221 vos_ssr_protect(__func__);
10222 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10223 vos_ssr_unprotect(__func__);
10224
10225 return ret;
10226}
Kiet Lam10841362013-11-01 11:36:50 +053010227/* FUNCTION: wlan_hdd_change_country_code_cd
10228* to wait for contry code completion
10229*/
10230void* wlan_hdd_change_country_code_cb(void *pAdapter)
10231{
10232 hdd_adapter_t *call_back_pAdapter = pAdapter;
10233 complete(&call_back_pAdapter->change_country_code);
10234 return NULL;
10235}
10236
Jeff Johnson295189b2012-06-20 16:38:30 -070010237/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010238 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10240 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010241int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 struct net_device *ndev,
10243 enum nl80211_iftype type,
10244 u32 *flags,
10245 struct vif_params *params
10246 )
10247{
10248 struct wireless_dev *wdev;
10249 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010250 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010251 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 tCsrRoamProfile *pRoamProfile = NULL;
10253 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010254 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 eMib_dot11DesiredBssType connectedBssType;
10256 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010257 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010258
10259 ENTER();
10260
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010261 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010262 {
10263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10264 "%s: Adapter context is null", __func__);
10265 return VOS_STATUS_E_FAILURE;
10266 }
10267
10268 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10269 if (!pHddCtx)
10270 {
10271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10272 "%s: HDD context is null", __func__);
10273 return VOS_STATUS_E_FAILURE;
10274 }
10275
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010276 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10277 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10278 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010279 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010280 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010281 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010282 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010283 }
10284
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010285 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10286 __func__, hdd_device_modetoString(pAdapter->device_mode),
10287 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010288
Agarwal Ashish51325b52014-06-16 16:50:49 +053010289 if (vos_max_concurrent_connections_reached()) {
10290 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10291 return -EINVAL;
10292 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010293 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 wdev = ndev->ieee80211_ptr;
10295
10296#ifdef WLAN_BTAMP_FEATURE
10297 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10298 (NL80211_IFTYPE_ADHOC == type)||
10299 (NL80211_IFTYPE_AP == type)||
10300 (NL80211_IFTYPE_P2P_GO == type))
10301 {
10302 pHddCtx->isAmpAllowed = VOS_FALSE;
10303 // stop AMP traffic
10304 status = WLANBAP_StopAmp();
10305 if(VOS_STATUS_SUCCESS != status )
10306 {
10307 pHddCtx->isAmpAllowed = VOS_TRUE;
10308 hddLog(VOS_TRACE_LEVEL_FATAL,
10309 "%s: Failed to stop AMP", __func__);
10310 return -EINVAL;
10311 }
10312 }
10313#endif //WLAN_BTAMP_FEATURE
10314 /* Reset the current device mode bit mask*/
10315 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10316
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010317 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10318 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10319 (type == NL80211_IFTYPE_P2P_GO)))
10320 {
10321 /* Notify Mode change in case of concurrency.
10322 * Below function invokes TDLS teardown Functionality Since TDLS is
10323 * not Supported in case of concurrency i.e Once P2P session
10324 * is detected disable offchannel and teardown TDLS links
10325 */
10326 hddLog(LOG1,
10327 FL("Device mode = %d Interface type = %d"),
10328 pAdapter->device_mode, type);
10329 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10330 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010331
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010334 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 )
10336 {
10337 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010338 if (!pWextState)
10339 {
10340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10341 "%s: pWextState is null", __func__);
10342 return VOS_STATUS_E_FAILURE;
10343 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010344 pRoamProfile = &pWextState->roamProfile;
10345 LastBSSType = pRoamProfile->BSSType;
10346
10347 switch (type)
10348 {
10349 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 hddLog(VOS_TRACE_LEVEL_INFO,
10352 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10353 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010354#ifdef WLAN_FEATURE_11AC
10355 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10356 {
10357 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10358 }
10359#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010360 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010361 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010363 //Check for sub-string p2p to confirm its a p2p interface
10364 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010365 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010366#ifdef FEATURE_WLAN_TDLS
10367 mutex_lock(&pHddCtx->tdls_lock);
10368 wlan_hdd_tdls_exit(pAdapter, TRUE);
10369 mutex_unlock(&pHddCtx->tdls_lock);
10370#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010371 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10372 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10373 }
10374 else
10375 {
10376 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010378 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010380
Jeff Johnson295189b2012-06-20 16:38:30 -070010381 case NL80211_IFTYPE_ADHOC:
10382 hddLog(VOS_TRACE_LEVEL_INFO,
10383 "%s: setting interface Type to ADHOC", __func__);
10384 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10385 pRoamProfile->phyMode =
10386 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010387 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010388 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010389 hdd_set_ibss_ops( pAdapter );
10390 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010391
10392 status = hdd_sta_id_hash_attach(pAdapter);
10393 if (VOS_STATUS_SUCCESS != status) {
10394 hddLog(VOS_TRACE_LEVEL_ERROR,
10395 FL("Failed to initialize hash for IBSS"));
10396 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 break;
10398
10399 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 {
10402 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10403 "%s: setting interface Type to %s", __func__,
10404 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10405
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010406 //Cancel any remain on channel for GO mode
10407 if (NL80211_IFTYPE_P2P_GO == type)
10408 {
10409 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10410 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010411 if (NL80211_IFTYPE_AP == type)
10412 {
10413 /* As Loading WLAN Driver one interface being created for p2p device
10414 * address. This will take one HW STA and the max number of clients
10415 * that can connect to softAP will be reduced by one. so while changing
10416 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10417 * interface as it is not required in SoftAP mode.
10418 */
10419
10420 // Get P2P Adapter
10421 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10422
10423 if (pP2pAdapter)
10424 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010425 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010426 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010427 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10428 }
10429 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010430 //Disable IMPS & BMPS for SAP/GO
10431 if(VOS_STATUS_E_FAILURE ==
10432 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10433 {
10434 //Fail to Exit BMPS
10435 VOS_ASSERT(0);
10436 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010437
10438 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10439
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010440#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010441
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010442 /* A Mutex Lock is introduced while changing the mode to
10443 * protect the concurrent access for the Adapters by TDLS
10444 * module.
10445 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010446 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010447#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010449 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10452 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010453#ifdef FEATURE_WLAN_TDLS
10454 mutex_unlock(&pHddCtx->tdls_lock);
10455#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010456 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10457 (pConfig->apRandomBssidEnabled))
10458 {
10459 /* To meet Android requirements create a randomized
10460 MAC address of the form 02:1A:11:Fx:xx:xx */
10461 get_random_bytes(&ndev->dev_addr[3], 3);
10462 ndev->dev_addr[0] = 0x02;
10463 ndev->dev_addr[1] = 0x1A;
10464 ndev->dev_addr[2] = 0x11;
10465 ndev->dev_addr[3] |= 0xF0;
10466 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10467 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010468 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10469 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010470 }
10471
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 hdd_set_ap_ops( pAdapter->dev );
10473
Kiet Lam10841362013-11-01 11:36:50 +053010474 /* This is for only SAP mode where users can
10475 * control country through ini.
10476 * P2P GO follows station country code
10477 * acquired during the STA scanning. */
10478 if((NL80211_IFTYPE_AP == type) &&
10479 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10480 {
10481 int status = 0;
10482 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10483 "%s: setting country code from INI ", __func__);
10484 init_completion(&pAdapter->change_country_code);
10485 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10486 (void *)(tSmeChangeCountryCallback)
10487 wlan_hdd_change_country_code_cb,
10488 pConfig->apCntryCode, pAdapter,
10489 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010490 eSIR_FALSE,
10491 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010492 if (eHAL_STATUS_SUCCESS == status)
10493 {
10494 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010495 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010496 &pAdapter->change_country_code,
10497 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010498 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010499 {
10500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010501 FL("SME Timed out while setting country code %ld"),
10502 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010503
10504 if (pHddCtx->isLogpInProgress)
10505 {
10506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10507 "%s: LOGP in Progress. Ignore!!!", __func__);
10508 return -EAGAIN;
10509 }
Kiet Lam10841362013-11-01 11:36:50 +053010510 }
10511 }
10512 else
10513 {
10514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010515 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010516 return -EINVAL;
10517 }
10518 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 status = hdd_init_ap_mode(pAdapter);
10520 if(status != VOS_STATUS_SUCCESS)
10521 {
10522 hddLog(VOS_TRACE_LEVEL_FATAL,
10523 "%s: Error initializing the ap mode", __func__);
10524 return -EINVAL;
10525 }
10526 hdd_set_conparam(1);
10527
Nirav Shah7e3c8132015-06-22 23:51:42 +053010528 status = hdd_sta_id_hash_attach(pAdapter);
10529 if (VOS_STATUS_SUCCESS != status)
10530 {
10531 hddLog(VOS_TRACE_LEVEL_ERROR,
10532 FL("Failed to initialize hash for AP"));
10533 return -EINVAL;
10534 }
10535
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 /*interface type changed update in wiphy structure*/
10537 if(wdev)
10538 {
10539 wdev->iftype = type;
10540 pHddCtx->change_iface = type;
10541 }
10542 else
10543 {
10544 hddLog(VOS_TRACE_LEVEL_ERROR,
10545 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10546 return -EINVAL;
10547 }
10548 goto done;
10549 }
10550
10551 default:
10552 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10553 __func__);
10554 return -EOPNOTSUPP;
10555 }
10556 }
10557 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010558 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010559 )
10560 {
10561 switch(type)
10562 {
10563 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010566
10567 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010568#ifdef FEATURE_WLAN_TDLS
10569
10570 /* A Mutex Lock is introduced while changing the mode to
10571 * protect the concurrent access for the Adapters by TDLS
10572 * module.
10573 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010574 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010575#endif
c_hpothu002231a2015-02-05 14:58:51 +053010576 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010578 //Check for sub-string p2p to confirm its a p2p interface
10579 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010580 {
10581 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10582 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10583 }
10584 else
10585 {
10586 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010588 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 hdd_set_conparam(0);
10590 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10592 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010593#ifdef FEATURE_WLAN_TDLS
10594 mutex_unlock(&pHddCtx->tdls_lock);
10595#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010596 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 if( VOS_STATUS_SUCCESS != status )
10598 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010599 /* In case of JB, for P2P-GO, only change interface will be called,
10600 * This is the right place to enable back bmps_imps()
10601 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010602 if (pHddCtx->hdd_wlan_suspended)
10603 {
10604 hdd_set_pwrparams(pHddCtx);
10605 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010606 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 goto done;
10608 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10612 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010613 goto done;
10614 default:
10615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10616 __func__);
10617 return -EOPNOTSUPP;
10618
10619 }
10620
10621 }
10622 else
10623 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010624 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10625 __func__, hdd_device_modetoString(pAdapter->device_mode),
10626 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 return -EOPNOTSUPP;
10628 }
10629
10630
10631 if(pRoamProfile)
10632 {
10633 if ( LastBSSType != pRoamProfile->BSSType )
10634 {
10635 /*interface type changed update in wiphy structure*/
10636 wdev->iftype = type;
10637
10638 /*the BSS mode changed, We need to issue disconnect
10639 if connected or in IBSS disconnect state*/
10640 if ( hdd_connGetConnectedBssType(
10641 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10642 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10643 {
10644 /*need to issue a disconnect to CSR.*/
10645 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10646 if( eHAL_STATUS_SUCCESS ==
10647 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10648 pAdapter->sessionId,
10649 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10650 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010651 ret = wait_for_completion_interruptible_timeout(
10652 &pAdapter->disconnect_comp_var,
10653 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10654 if (ret <= 0)
10655 {
10656 hddLog(VOS_TRACE_LEVEL_ERROR,
10657 FL("wait on disconnect_comp_var failed %ld"), ret);
10658 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010659 }
10660 }
10661 }
10662 }
10663
10664done:
10665 /*set bitmask based on updated value*/
10666 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010667
10668 /* Only STA mode support TM now
10669 * all other mode, TM feature should be disabled */
10670 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10671 (~VOS_STA & pHddCtx->concurrency_mode) )
10672 {
10673 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10674 }
10675
Jeff Johnson295189b2012-06-20 16:38:30 -070010676#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010677 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010678 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010679 {
10680 //we are ok to do AMP
10681 pHddCtx->isAmpAllowed = VOS_TRUE;
10682 }
10683#endif //WLAN_BTAMP_FEATURE
10684 EXIT();
10685 return 0;
10686}
10687
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010688/*
10689 * FUNCTION: wlan_hdd_cfg80211_change_iface
10690 * wrapper function to protect the actual implementation from SSR.
10691 */
10692int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10693 struct net_device *ndev,
10694 enum nl80211_iftype type,
10695 u32 *flags,
10696 struct vif_params *params
10697 )
10698{
10699 int ret;
10700
10701 vos_ssr_protect(__func__);
10702 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10703 vos_ssr_unprotect(__func__);
10704
10705 return ret;
10706}
10707
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010708#ifdef FEATURE_WLAN_TDLS
10709static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010710 struct net_device *dev,
10711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10712 const u8 *mac,
10713#else
10714 u8 *mac,
10715#endif
10716 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010717{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010718 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010719 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010720 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010721 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010722 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010723 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010724
10725 ENTER();
10726
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010727 if (!dev) {
10728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10729 return -EINVAL;
10730 }
10731
10732 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10733 if (!pAdapter) {
10734 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10735 return -EINVAL;
10736 }
10737
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010738 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010739 {
10740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10741 "Invalid arguments");
10742 return -EINVAL;
10743 }
Hoonki Lee27511902013-03-14 18:19:06 -070010744
10745 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10746 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10747 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010749 "%s: TDLS mode is disabled OR not enabled in FW."
10750 MAC_ADDRESS_STR " Request declined.",
10751 __func__, MAC_ADDR_ARRAY(mac));
10752 return -ENOTSUPP;
10753 }
10754
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010755 if (pHddCtx->isLogpInProgress)
10756 {
10757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10758 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010759 wlan_hdd_tdls_set_link_status(pAdapter,
10760 mac,
10761 eTDLS_LINK_IDLE,
10762 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010763 return -EBUSY;
10764 }
10765
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010766 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010767 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010768
10769 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010771 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10772 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010773 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010774 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010775 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010776
10777 /* in add station, we accept existing valid staId if there is */
10778 if ((0 == update) &&
10779 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10780 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010781 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010783 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010784 " link_status %d. staId %d. add station ignored.",
10785 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010786 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010787 return 0;
10788 }
10789 /* in change station, we accept only when staId is valid */
10790 if ((1 == update) &&
10791 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10792 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10793 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010794 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010796 "%s: " MAC_ADDRESS_STR
10797 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010798 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10799 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10800 mutex_unlock(&pHddCtx->tdls_lock);
10801 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010802 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010803 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010804
10805 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010806 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010807 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10809 "%s: " MAC_ADDRESS_STR
10810 " TDLS setup is ongoing. Request declined.",
10811 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010812 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010813 }
10814
10815 /* first to check if we reached to maximum supported TDLS peer.
10816 TODO: for now, return -EPERM looks working fine,
10817 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010818 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10819 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010820 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10822 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010823 " TDLS Max peer already connected. Request declined."
10824 " Num of peers (%d), Max allowed (%d).",
10825 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10826 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010827 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010828 }
10829 else
10830 {
10831 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010832 mutex_lock(&pHddCtx->tdls_lock);
10833 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010834 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010835 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010836 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10838 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10839 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010840 return -EPERM;
10841 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010842 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010843 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010844 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010845 wlan_hdd_tdls_set_link_status(pAdapter,
10846 mac,
10847 eTDLS_LINK_CONNECTING,
10848 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010849
Jeff Johnsond75fe012013-04-06 10:53:06 -070010850 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010851 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010852 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010854 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010855 if(StaParams->htcap_present)
10856 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010858 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010860 "ht_capa->extended_capabilities: %0x",
10861 StaParams->HTCap.extendedHtCapInfo);
10862 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010864 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010866 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010867 if(StaParams->vhtcap_present)
10868 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010870 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10871 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10872 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10873 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010874 {
10875 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010877 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010879 "[%d]: %x ", i, StaParams->supported_rates[i]);
10880 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010881 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010882 else if ((1 == update) && (NULL == StaParams))
10883 {
10884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10885 "%s : update is true, but staParams is NULL. Error!", __func__);
10886 return -EPERM;
10887 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010888
10889 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10890
10891 if (!update)
10892 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010893 /*Before adding sta make sure that device exited from BMPS*/
10894 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10895 {
10896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10897 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10898 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10899 if (status != VOS_STATUS_SUCCESS) {
10900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10901 }
10902 }
10903
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010904 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010905 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010906 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010907 hddLog(VOS_TRACE_LEVEL_ERROR,
10908 FL("Failed to add TDLS peer STA. Enable Bmps"));
10909 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010910 return -EPERM;
10911 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010912 }
10913 else
10914 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010915 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010916 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010917 if (ret != eHAL_STATUS_SUCCESS) {
10918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10919 return -EPERM;
10920 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010921 }
10922
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010923 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010924 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10925
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010926 mutex_lock(&pHddCtx->tdls_lock);
10927 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
10928
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010929 if ((pTdlsPeer != NULL) &&
10930 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010931 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010932 hddLog(VOS_TRACE_LEVEL_ERROR,
10933 FL("peer link status %u"), pTdlsPeer->link_status);
10934 mutex_unlock(&pHddCtx->tdls_lock);
10935 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010936 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053010937 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010938
Masti, Narayanraddi07262462016-01-19 12:40:06 +053010939 if (ret <= 0)
10940 {
10941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10942 "%s: timeout waiting for tdls add station indication %ld",
10943 __func__, ret);
10944 goto error;
10945 }
10946
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010947 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10948 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010950 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010951 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010952 }
10953
10954 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010955
10956error:
Atul Mittal115287b2014-07-08 13:26:33 +053010957 wlan_hdd_tdls_set_link_status(pAdapter,
10958 mac,
10959 eTDLS_LINK_IDLE,
10960 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010961 return -EPERM;
10962
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010963}
10964#endif
10965
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010966static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010967 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010968#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10969 const u8 *mac,
10970#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010972#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010973 struct station_parameters *params)
10974{
10975 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010976 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010977 hdd_context_t *pHddCtx;
10978 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010980 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010981#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010982 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010983 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010984 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053010985 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010986#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010987
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010988 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010989
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010990 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010991 if ((NULL == pAdapter))
10992 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010994 "invalid adapter ");
10995 return -EINVAL;
10996 }
10997
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010998 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10999 TRACE_CODE_HDD_CHANGE_STATION,
11000 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053011001 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053011002
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011003 ret = wlan_hdd_validate_context(pHddCtx);
11004 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053011005 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011006 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011007 }
11008
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011009 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11010
11011 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011012 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11014 "invalid HDD station context");
11015 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011016 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
11018
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011019 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11020 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011022 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011024 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 WLANTL_STA_AUTHENTICATED);
11026
Gopichand Nakkala29149562013-05-10 21:43:41 +053011027 if (status != VOS_STATUS_SUCCESS)
11028 {
11029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11030 "%s: Not able to change TL state to AUTHENTICATED", __func__);
11031 return -EINVAL;
11032 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011033 }
11034 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070011035 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
11036 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011037#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011038 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11039 StaParams.capability = params->capability;
11040 StaParams.uapsd_queues = params->uapsd_queues;
11041 StaParams.max_sp = params->max_sp;
11042
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011043 /* Convert (first channel , number of channels) tuple to
11044 * the total list of channels. This goes with the assumption
11045 * that if the first channel is < 14, then the next channels
11046 * are an incremental of 1 else an incremental of 4 till the number
11047 * of channels.
11048 */
11049 if (0 != params->supported_channels_len) {
11050 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
11051 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
11052 {
11053 int wifi_chan_index;
11054 StaParams.supported_channels[j] = params->supported_channels[i];
11055 wifi_chan_index =
11056 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
11057 no_of_channels = params->supported_channels[i+1];
11058 for(k=1; k <= no_of_channels; k++)
11059 {
11060 StaParams.supported_channels[j+1] =
11061 StaParams.supported_channels[j] + wifi_chan_index;
11062 j+=1;
11063 }
11064 }
11065 StaParams.supported_channels_len = j;
11066 }
11067 vos_mem_copy(StaParams.supported_oper_classes,
11068 params->supported_oper_classes,
11069 params->supported_oper_classes_len);
11070 StaParams.supported_oper_classes_len =
11071 params->supported_oper_classes_len;
11072
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011073 if (0 != params->ext_capab_len)
11074 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
11075 sizeof(StaParams.extn_capability));
11076
11077 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011078 {
11079 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011080 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011081 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011082
11083 StaParams.supported_rates_len = params->supported_rates_len;
11084
11085 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
11086 * The supported_rates array , for all the structures propogating till Add Sta
11087 * to the firmware has to be modified , if the supplicant (ieee80211) is
11088 * modified to send more rates.
11089 */
11090
11091 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
11092 */
11093 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
11094 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
11095
11096 if (0 != StaParams.supported_rates_len) {
11097 int i = 0;
11098 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
11099 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011101 "Supported Rates with Length %d", StaParams.supported_rates_len);
11102 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070011103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011104 "[%d]: %0x", i, StaParams.supported_rates[i]);
11105 }
11106
11107 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070011108 {
11109 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011110 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011111 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011112
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011113 if (0 != params->ext_capab_len ) {
11114 /*Define A Macro : TODO Sunil*/
11115 if ((1<<4) & StaParams.extn_capability[3]) {
11116 isBufSta = 1;
11117 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011118 /* TDLS Channel Switching Support */
11119 if ((1<<6) & StaParams.extn_capability[3]) {
11120 isOffChannelSupported = 1;
11121 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011122 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011123
11124 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053011125 (params->ht_capa || params->vht_capa ||
11126 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011127 /* TDLS Peer is WME/QoS capable */
11128 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011129
11130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11131 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
11132 __func__, isQosWmmSta, StaParams.htcap_present);
11133
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011134 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11135 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053011136 isOffChannelSupported,
11137 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011138
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011139 if (VOS_STATUS_SUCCESS != status) {
11140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11141 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11142 return -EINVAL;
11143 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011144 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11145
11146 if (VOS_STATUS_SUCCESS != status) {
11147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11148 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11149 return -EINVAL;
11150 }
11151 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011152#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011153 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011154 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 return status;
11156}
11157
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11159static int wlan_hdd_change_station(struct wiphy *wiphy,
11160 struct net_device *dev,
11161 const u8 *mac,
11162 struct station_parameters *params)
11163#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011164static int wlan_hdd_change_station(struct wiphy *wiphy,
11165 struct net_device *dev,
11166 u8 *mac,
11167 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011168#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011169{
11170 int ret;
11171
11172 vos_ssr_protect(__func__);
11173 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11174 vos_ssr_unprotect(__func__);
11175
11176 return ret;
11177}
11178
Jeff Johnson295189b2012-06-20 16:38:30 -070011179/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011180 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 * This function is used to initialize the key information
11182 */
11183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011184static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 struct net_device *ndev,
11186 u8 key_index, bool pairwise,
11187 const u8 *mac_addr,
11188 struct key_params *params
11189 )
11190#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011191static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 struct net_device *ndev,
11193 u8 key_index, const u8 *mac_addr,
11194 struct key_params *params
11195 )
11196#endif
11197{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011198 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 tCsrRoamSetKey setKey;
11200 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011201 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011202 v_U32_t roamId= 0xFF;
11203 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 hdd_hostapd_state_t *pHostapdState;
11205 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011206 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011207 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011208
11209 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011210
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011211 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11212 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11213 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011214 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11215 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011216 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011217 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011218 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011219 }
11220
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011221 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11222 __func__, hdd_device_modetoString(pAdapter->device_mode),
11223 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011224
11225 if (CSR_MAX_NUM_KEY <= key_index)
11226 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011228 key_index);
11229
11230 return -EINVAL;
11231 }
11232
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011233 if (CSR_MAX_KEY_LEN < params->key_len)
11234 {
11235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11236 params->key_len);
11237
11238 return -EINVAL;
11239 }
11240
11241 hddLog(VOS_TRACE_LEVEL_INFO,
11242 "%s: called with key index = %d & key length %d",
11243 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011244
11245 /*extract key idx, key len and key*/
11246 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11247 setKey.keyId = key_index;
11248 setKey.keyLength = params->key_len;
11249 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11250
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011251 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011252 {
11253 case WLAN_CIPHER_SUITE_WEP40:
11254 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11255 break;
11256
11257 case WLAN_CIPHER_SUITE_WEP104:
11258 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11259 break;
11260
11261 case WLAN_CIPHER_SUITE_TKIP:
11262 {
11263 u8 *pKey = &setKey.Key[0];
11264 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11265
11266 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11267
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011268 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011269
11270 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011271 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 |--------------|----------|----------|
11273 <---16bytes---><--8bytes--><--8bytes-->
11274
11275 */
11276 /*Sme expects the 32 bytes key to be in the below order
11277
11278 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011279 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 |--------------|----------|----------|
11281 <---16bytes---><--8bytes--><--8bytes-->
11282 */
11283 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011284 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011285
11286 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011287 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011288
11289 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011290 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011291
11292
11293 break;
11294 }
11295
11296 case WLAN_CIPHER_SUITE_CCMP:
11297 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11298 break;
11299
11300#ifdef FEATURE_WLAN_WAPI
11301 case WLAN_CIPHER_SUITE_SMS4:
11302 {
11303 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11304 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11305 params->key, params->key_len);
11306 return 0;
11307 }
11308#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011309
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011310#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 case WLAN_CIPHER_SUITE_KRK:
11312 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11313 break;
11314#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011315
11316#ifdef WLAN_FEATURE_11W
11317 case WLAN_CIPHER_SUITE_AES_CMAC:
11318 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011319 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011320#endif
11321
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011324 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011325 status = -EOPNOTSUPP;
11326 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 }
11328
11329 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11330 __func__, setKey.encType);
11331
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011332 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011333#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11334 (!pairwise)
11335#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011336 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011337#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011338 )
11339 {
11340 /* set group key*/
11341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11342 "%s- %d: setting Broadcast key",
11343 __func__, __LINE__);
11344 setKey.keyDirection = eSIR_RX_ONLY;
11345 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11346 }
11347 else
11348 {
11349 /* set pairwise key*/
11350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11351 "%s- %d: setting pairwise key",
11352 __func__, __LINE__);
11353 setKey.keyDirection = eSIR_TX_RX;
11354 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11355 }
11356 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11357 {
11358 setKey.keyDirection = eSIR_TX_RX;
11359 /*Set the group key*/
11360 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11361 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011362
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011363 if ( 0 != status )
11364 {
11365 hddLog(VOS_TRACE_LEVEL_ERROR,
11366 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011367 status = -EINVAL;
11368 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011369 }
11370 /*Save the keys here and call sme_RoamSetKey for setting
11371 the PTK after peer joins the IBSS network*/
11372 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11373 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011374 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011375 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011376 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11377 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11378 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011380 if( pHostapdState->bssState == BSS_START )
11381 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011382 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11383 vos_status = wlan_hdd_check_ula_done(pAdapter);
11384
11385 if ( vos_status != VOS_STATUS_SUCCESS )
11386 {
11387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11388 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11389 __LINE__, vos_status );
11390
11391 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11392
11393 status = -EINVAL;
11394 goto end;
11395 }
11396
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11398
11399 if ( status != eHAL_STATUS_SUCCESS )
11400 {
11401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11402 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11403 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011404 status = -EINVAL;
11405 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 }
11407 }
11408
11409 /* Saving WEP keys */
11410 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11411 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11412 {
11413 //Save the wep key in ap context. Issue setkey after the BSS is started.
11414 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11415 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11416 }
11417 else
11418 {
11419 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011420 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11422 }
11423 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011424 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11425 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 {
11427 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11428 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11429
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11431 if (!pairwise)
11432#else
11433 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11434#endif
11435 {
11436 /* set group key*/
11437 if (pHddStaCtx->roam_info.deferKeyComplete)
11438 {
11439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11440 "%s- %d: Perform Set key Complete",
11441 __func__, __LINE__);
11442 hdd_PerformRoamSetKeyComplete(pAdapter);
11443 }
11444 }
11445
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11447
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011448 pWextState->roamProfile.Keys.defaultIndex = key_index;
11449
11450
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011451 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011452 params->key, params->key_len);
11453
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011454
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11456
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011457 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011459 __func__, setKey.peerMac[0], setKey.peerMac[1],
11460 setKey.peerMac[2], setKey.peerMac[3],
11461 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 setKey.keyDirection);
11463
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011464 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011465
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011466 if ( vos_status != VOS_STATUS_SUCCESS )
11467 {
11468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11470 __LINE__, vos_status );
11471
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011472 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011473
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011474 status = -EINVAL;
11475 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011476
11477 }
11478
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011479#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011480 /* The supplicant may attempt to set the PTK once pre-authentication
11481 is done. Save the key in the UMAC and include it in the ADD BSS
11482 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011483 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011484 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011485 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011486 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11487 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011488 status = 0;
11489 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011490 }
11491 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11492 {
11493 hddLog(VOS_TRACE_LEVEL_ERROR,
11494 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011495 status = -EINVAL;
11496 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011497 }
11498#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011499
11500 /* issue set key request to SME*/
11501 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11502 pAdapter->sessionId, &setKey, &roamId );
11503
11504 if ( 0 != status )
11505 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011506 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11508 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011509 status = -EINVAL;
11510 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 }
11512
11513
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011514 /* in case of IBSS as there was no information available about WEP keys during
11515 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011517 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11518 !( ( IW_AUTH_KEY_MGMT_802_1X
11519 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11521 )
11522 &&
11523 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11524 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11525 )
11526 )
11527 {
11528 setKey.keyDirection = eSIR_RX_ONLY;
11529 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11530
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011531 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011533 __func__, setKey.peerMac[0], setKey.peerMac[1],
11534 setKey.peerMac[2], setKey.peerMac[3],
11535 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 setKey.keyDirection);
11537
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011538 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011539 pAdapter->sessionId, &setKey, &roamId );
11540
11541 if ( 0 != status )
11542 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011543 hddLog(VOS_TRACE_LEVEL_ERROR,
11544 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 __func__, status);
11546 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011547 status = -EINVAL;
11548 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 }
11550 }
11551 }
11552
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011553end:
11554 /* Need to clear any trace of key value in the memory.
11555 * Thus zero out the memory even though it is local
11556 * variable.
11557 */
11558 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011559 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011560 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011561}
11562
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11564static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11565 struct net_device *ndev,
11566 u8 key_index, bool pairwise,
11567 const u8 *mac_addr,
11568 struct key_params *params
11569 )
11570#else
11571static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11572 struct net_device *ndev,
11573 u8 key_index, const u8 *mac_addr,
11574 struct key_params *params
11575 )
11576#endif
11577{
11578 int ret;
11579 vos_ssr_protect(__func__);
11580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11581 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11582 mac_addr, params);
11583#else
11584 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11585 params);
11586#endif
11587 vos_ssr_unprotect(__func__);
11588
11589 return ret;
11590}
11591
Jeff Johnson295189b2012-06-20 16:38:30 -070011592/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011593 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 * This function is used to get the key information
11595 */
11596#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011597static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011598 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011600 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011601 const u8 *mac_addr, void *cookie,
11602 void (*callback)(void *cookie, struct key_params*)
11603 )
11604#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011605static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 struct net_device *ndev,
11608 u8 key_index, const u8 *mac_addr, void *cookie,
11609 void (*callback)(void *cookie, struct key_params*)
11610 )
11611#endif
11612{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011613 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011614 hdd_wext_state_t *pWextState = NULL;
11615 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011617 hdd_context_t *pHddCtx;
11618 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011619
11620 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011621
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011622 if (NULL == pAdapter)
11623 {
11624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11625 "%s: HDD adapter is Null", __func__);
11626 return -ENODEV;
11627 }
11628
11629 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11630 ret = wlan_hdd_validate_context(pHddCtx);
11631 if (0 != ret)
11632 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011633 return ret;
11634 }
11635
11636 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11637 pRoamProfile = &(pWextState->roamProfile);
11638
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11640 __func__, hdd_device_modetoString(pAdapter->device_mode),
11641 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011642
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 memset(&params, 0, sizeof(params));
11644
11645 if (CSR_MAX_NUM_KEY <= key_index)
11646 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011649 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011650
11651 switch(pRoamProfile->EncryptionType.encryptionType[0])
11652 {
11653 case eCSR_ENCRYPT_TYPE_NONE:
11654 params.cipher = IW_AUTH_CIPHER_NONE;
11655 break;
11656
11657 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11658 case eCSR_ENCRYPT_TYPE_WEP40:
11659 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11660 break;
11661
11662 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11663 case eCSR_ENCRYPT_TYPE_WEP104:
11664 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11665 break;
11666
11667 case eCSR_ENCRYPT_TYPE_TKIP:
11668 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11669 break;
11670
11671 case eCSR_ENCRYPT_TYPE_AES:
11672 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11673 break;
11674
11675 default:
11676 params.cipher = IW_AUTH_CIPHER_NONE;
11677 break;
11678 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011679
c_hpothuaaf19692014-05-17 17:01:48 +053011680 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11681 TRACE_CODE_HDD_CFG80211_GET_KEY,
11682 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011683
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11685 params.seq_len = 0;
11686 params.seq = NULL;
11687 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11688 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011689 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 return 0;
11691}
11692
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11694static int wlan_hdd_cfg80211_get_key(
11695 struct wiphy *wiphy,
11696 struct net_device *ndev,
11697 u8 key_index, bool pairwise,
11698 const u8 *mac_addr, void *cookie,
11699 void (*callback)(void *cookie, struct key_params*)
11700 )
11701#else
11702static int wlan_hdd_cfg80211_get_key(
11703 struct wiphy *wiphy,
11704 struct net_device *ndev,
11705 u8 key_index, const u8 *mac_addr, void *cookie,
11706 void (*callback)(void *cookie, struct key_params*)
11707 )
11708#endif
11709{
11710 int ret;
11711
11712 vos_ssr_protect(__func__);
11713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11714 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11715 mac_addr, cookie, callback);
11716#else
11717 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11718 callback);
11719#endif
11720 vos_ssr_unprotect(__func__);
11721
11722 return ret;
11723}
11724
Jeff Johnson295189b2012-06-20 16:38:30 -070011725/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011726 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 * This function is used to delete the key information
11728 */
11729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011730static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732 u8 key_index,
11733 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 const u8 *mac_addr
11735 )
11736#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011737static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 struct net_device *ndev,
11739 u8 key_index,
11740 const u8 *mac_addr
11741 )
11742#endif
11743{
11744 int status = 0;
11745
11746 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011747 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 //it is observed that this is invalidating peer
11749 //key index whenever re-key is done. This is affecting data link.
11750 //It should be ok to ignore del_key.
11751#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011752 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11753 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11755 tCsrRoamSetKey setKey;
11756 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011757
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 ENTER();
11759
11760 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11761 __func__,pAdapter->device_mode);
11762
11763 if (CSR_MAX_NUM_KEY <= key_index)
11764 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 key_index);
11767
11768 return -EINVAL;
11769 }
11770
11771 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11772 setKey.keyId = key_index;
11773
11774 if (mac_addr)
11775 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11776 else
11777 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11778
11779 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11780
11781 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011783 )
11784 {
11785
11786 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11788 if( pHostapdState->bssState == BSS_START)
11789 {
11790 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 if ( status != eHAL_STATUS_SUCCESS )
11793 {
11794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11795 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11796 __LINE__, status );
11797 }
11798 }
11799 }
11800 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011801 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 )
11803 {
11804 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11805
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011806 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11807
11808 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011809 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011810 __func__, setKey.peerMac[0], setKey.peerMac[1],
11811 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011812 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011813 if(pAdapter->sessionCtx.station.conn_info.connState ==
11814 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011816 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011818
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 if ( 0 != status )
11820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011821 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 "%s: sme_RoamSetKey failure, returned %d",
11823 __func__, status);
11824 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11825 return -EINVAL;
11826 }
11827 }
11828 }
11829#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011830 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 return status;
11832}
11833
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11835static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11836 struct net_device *ndev,
11837 u8 key_index,
11838 bool pairwise,
11839 const u8 *mac_addr
11840 )
11841#else
11842static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11843 struct net_device *ndev,
11844 u8 key_index,
11845 const u8 *mac_addr
11846 )
11847#endif
11848{
11849 int ret;
11850
11851 vos_ssr_protect(__func__);
11852#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11853 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11854 mac_addr);
11855#else
11856 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11857#endif
11858 vos_ssr_unprotect(__func__);
11859
11860 return ret;
11861}
11862
Jeff Johnson295189b2012-06-20 16:38:30 -070011863/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011864 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011865 * This function is used to set the default tx key index
11866 */
11867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011868static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 struct net_device *ndev,
11870 u8 key_index,
11871 bool unicast, bool multicast)
11872#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011873static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 struct net_device *ndev,
11875 u8 key_index)
11876#endif
11877{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011878 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011879 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011880 hdd_wext_state_t *pWextState;
11881 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011882 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011883
11884 ENTER();
11885
Gopichand Nakkala29149562013-05-10 21:43:41 +053011886 if ((NULL == pAdapter))
11887 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011889 "invalid adapter");
11890 return -EINVAL;
11891 }
11892
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011893 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11894 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11895 pAdapter->sessionId, key_index));
11896
Gopichand Nakkala29149562013-05-10 21:43:41 +053011897 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11898 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11899
11900 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11901 {
11902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11903 "invalid Wext state or HDD context");
11904 return -EINVAL;
11905 }
11906
Arif Hussain6d2a3322013-11-17 19:50:10 -080011907 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011909
Jeff Johnson295189b2012-06-20 16:38:30 -070011910 if (CSR_MAX_NUM_KEY <= key_index)
11911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011913 key_index);
11914
11915 return -EINVAL;
11916 }
11917
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011918 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11919 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011920 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011921 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011922 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011923 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011924
Jeff Johnson295189b2012-06-20 16:38:30 -070011925 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011926 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011927 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011929 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011930 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011932 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011934 {
11935 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011937
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 tCsrRoamSetKey setKey;
11939 v_U32_t roamId= 0xFF;
11940 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011941
11942 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011944
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 Keys->defaultIndex = (u8)key_index;
11946 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11947 setKey.keyId = key_index;
11948 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011949
11950 vos_mem_copy(&setKey.Key[0],
11951 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011952 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011953
Gopichand Nakkala29149562013-05-10 21:43:41 +053011954 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011955
11956 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 &pHddStaCtx->conn_info.bssId[0],
11958 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011959
Gopichand Nakkala29149562013-05-10 21:43:41 +053011960 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11961 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11962 eCSR_ENCRYPT_TYPE_WEP104)
11963 {
11964 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11965 even though ap is configured for WEP-40 encryption. In this canse the key length
11966 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11967 type(104) and switching encryption type to 40*/
11968 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11969 eCSR_ENCRYPT_TYPE_WEP40;
11970 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11971 eCSR_ENCRYPT_TYPE_WEP40;
11972 }
11973
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011974 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011976
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011978 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011979 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011980
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 if ( 0 != status )
11982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011983 hddLog(VOS_TRACE_LEVEL_ERROR,
11984 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011985 status);
11986 return -EINVAL;
11987 }
11988 }
11989 }
11990
11991 /* In SoftAp mode setting key direction for default mode */
11992 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11993 {
11994 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11995 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11996 (eCSR_ENCRYPT_TYPE_AES !=
11997 pWextState->roamProfile.EncryptionType.encryptionType[0])
11998 )
11999 {
12000 /* Saving key direction for default key index to TX default */
12001 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12002 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
12003 }
12004 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012005 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 return status;
12007}
12008
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12010static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12011 struct net_device *ndev,
12012 u8 key_index,
12013 bool unicast, bool multicast)
12014#else
12015static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
12016 struct net_device *ndev,
12017 u8 key_index)
12018#endif
12019{
12020 int ret;
12021 vos_ssr_protect(__func__);
12022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12023 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
12024 multicast);
12025#else
12026 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
12027#endif
12028 vos_ssr_unprotect(__func__);
12029
12030 return ret;
12031}
12032
Jeff Johnson295189b2012-06-20 16:38:30 -070012033/*
12034 * FUNCTION: wlan_hdd_cfg80211_inform_bss
12035 * This function is used to inform the BSS details to nl80211 interface.
12036 */
12037static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
12038 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
12039{
12040 struct net_device *dev = pAdapter->dev;
12041 struct wireless_dev *wdev = dev->ieee80211_ptr;
12042 struct wiphy *wiphy = wdev->wiphy;
12043 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
12044 int chan_no;
12045 int ie_length;
12046 const char *ie;
12047 unsigned int freq;
12048 struct ieee80211_channel *chan;
12049 int rssi = 0;
12050 struct cfg80211_bss *bss = NULL;
12051
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 if( NULL == pBssDesc )
12053 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012054 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012055 return bss;
12056 }
12057
12058 chan_no = pBssDesc->channelId;
12059 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
12060 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
12061
12062 if( NULL == ie )
12063 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012064 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012065 return bss;
12066 }
12067
12068#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
12069 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
12070 {
12071 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12072 }
12073 else
12074 {
12075 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12076 }
12077#else
12078 freq = ieee80211_channel_to_frequency(chan_no);
12079#endif
12080
12081 chan = __ieee80211_get_channel(wiphy, freq);
12082
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053012083 if (!chan) {
12084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
12085 return NULL;
12086 }
12087
Abhishek Singhaee43942014-06-16 18:55:47 +053012088 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070012089
Anand N Sunkad9f80b742015-07-30 20:05:51 +053012090 return cfg80211_inform_bss(wiphy, chan,
12091#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12092 CFG80211_BSS_FTYPE_UNKNOWN,
12093#endif
12094 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070012096 pBssDesc->capabilityInfo,
12097 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053012098 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070012099}
12100
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053012101/*
12102 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
12103 * interface that BSS might have been lost.
12104 * @pAdapter: adaptor
12105 * @bssid: bssid which might have been lost
12106 *
12107 * Return: bss which is unlinked from kernel cache
12108 */
12109struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
12110 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
12111{
12112 struct net_device *dev = pAdapter->dev;
12113 struct wireless_dev *wdev = dev->ieee80211_ptr;
12114 struct wiphy *wiphy = wdev->wiphy;
12115 struct cfg80211_bss *bss = NULL;
12116
12117 bss = cfg80211_get_bss(wiphy, NULL, bssid,
12118 NULL,
12119 0,
12120#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS) \
12121 && !defined(IEEE80211_PRIVACY)
12122 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
12123#else
12124 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
12125#endif
12126 if (bss == NULL) {
12127 hddLog(LOGE, FL("BSS not present"));
12128 } else {
12129 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
12130 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
12131 cfg80211_unlink_bss(wiphy, bss);
12132 }
12133 return bss;
12134}
Jeff Johnson295189b2012-06-20 16:38:30 -070012135
12136
12137/*
12138 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
12139 * This function is used to inform the BSS details to nl80211 interface.
12140 */
12141struct cfg80211_bss*
12142wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
12143 tSirBssDescription *bss_desc
12144 )
12145{
12146 /*
12147 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
12148 already exists in bss data base of cfg80211 for that particular BSS ID.
12149 Using cfg80211_inform_bss_frame to update the bss entry instead of
12150 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
12151 now there is no possibility to get the mgmt(probe response) frame from PE,
12152 converting bss_desc to ieee80211_mgmt(probe response) and passing to
12153 cfg80211_inform_bss_frame.
12154 */
12155 struct net_device *dev = pAdapter->dev;
12156 struct wireless_dev *wdev = dev->ieee80211_ptr;
12157 struct wiphy *wiphy = wdev->wiphy;
12158 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012159#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12160 qcom_ie_age *qie_age = NULL;
12161 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12162#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012164#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012165 const char *ie =
12166 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12167 unsigned int freq;
12168 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012169 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012170 struct cfg80211_bss *bss_status = NULL;
12171 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12172 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012173 hdd_context_t *pHddCtx;
12174 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012175#ifdef WLAN_OPEN_SOURCE
12176 struct timespec ts;
12177#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012178
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012179
Wilson Yangf80a0542013-10-07 13:02:37 -070012180 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12181 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012182 if (0 != status)
12183 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012184 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012185 }
12186
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012187 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012188 if (!mgmt)
12189 {
12190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12191 "%s: memory allocation failed ", __func__);
12192 return NULL;
12193 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012194
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012196
12197#ifdef WLAN_OPEN_SOURCE
12198 /* Android does not want the timestamp from the frame.
12199 Instead it wants a monotonic increasing value */
12200 get_monotonic_boottime(&ts);
12201 mgmt->u.probe_resp.timestamp =
12202 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12203#else
12204 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12206 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012207
12208#endif
12209
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12211 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012212
12213#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12214 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12215 /* Assuming this is the last IE, copy at the end */
12216 ie_length -=sizeof(qcom_ie_age);
12217 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12218 qie_age->element_id = QCOM_VENDOR_IE_ID;
12219 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12220 qie_age->oui_1 = QCOM_OUI1;
12221 qie_age->oui_2 = QCOM_OUI2;
12222 qie_age->oui_3 = QCOM_OUI3;
12223 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Deepthi Gowri4480a3f2016-05-18 19:30:17 +053012224 qie_age->age = vos_timer_get_system_time() - bss_desc->nReceivedTime;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012225#endif
12226
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012228 if (bss_desc->fProbeRsp)
12229 {
12230 mgmt->frame_control |=
12231 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12232 }
12233 else
12234 {
12235 mgmt->frame_control |=
12236 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12237 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012238
12239#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012240 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12242 {
12243 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12244 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012245 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12247
12248 {
12249 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12250 }
12251 else
12252 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12254 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 kfree(mgmt);
12256 return NULL;
12257 }
12258#else
12259 freq = ieee80211_channel_to_frequency(chan_no);
12260#endif
12261 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012262 /*when the band is changed on the fly using the GUI, three things are done
12263 * 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)
12264 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12265 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12266 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12267 * and discards the channels correponding to previous band and calls back with zero bss results.
12268 * 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
12269 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12270 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12271 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12272 * So drop the bss and continue to next bss.
12273 */
12274 if(chan == NULL)
12275 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053012276 hddLog(VOS_TRACE_LEVEL_ERROR,
12277 FL("chan pointer is NULL, chan_no: %d freq: %d"),
12278 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070012279 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012280 return NULL;
12281 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012282 /*To keep the rssi icon of the connected AP in the scan window
12283 *and the rssi icon of the wireless networks in sync
12284 * */
12285 if (( eConnectionState_Associated ==
12286 pAdapter->sessionCtx.station.conn_info.connState ) &&
12287 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12288 pAdapter->sessionCtx.station.conn_info.bssId,
12289 WNI_CFG_BSSID_LEN)) &&
12290 (pHddCtx->hdd_wlan_suspended == FALSE))
12291 {
12292 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12293 rssi = (pAdapter->rssi * 100);
12294 }
12295 else
12296 {
12297 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12298 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012299
Nirav Shah20ac06f2013-12-12 18:14:06 +053012300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012301 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12302 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012303
Jeff Johnson295189b2012-06-20 16:38:30 -070012304 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12305 frame_len, rssi, GFP_KERNEL);
12306 kfree(mgmt);
12307 return bss_status;
12308}
12309
12310/*
12311 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12312 * This function is used to update the BSS data base of CFG8011
12313 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012314struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 tCsrRoamInfo *pRoamInfo
12316 )
12317{
12318 tCsrRoamConnectedProfile roamProfile;
12319 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12320 struct cfg80211_bss *bss = NULL;
12321
12322 ENTER();
12323
12324 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12325 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12326
12327 if (NULL != roamProfile.pBssDesc)
12328 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012329 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12330 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012331
12332 if (NULL == bss)
12333 {
12334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12335 __func__);
12336 }
12337
12338 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12339 }
12340 else
12341 {
12342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12343 __func__);
12344 }
12345 return bss;
12346}
12347
12348/*
12349 * FUNCTION: wlan_hdd_cfg80211_update_bss
12350 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012351static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12352 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012353 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012354{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012355 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 tCsrScanResultInfo *pScanResult;
12357 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012358 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012359 tScanResultHandle pResult;
12360 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012361 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012362 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012364
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012365 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12366 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12367 NO_SESSION, pAdapter->sessionId));
12368
Wilson Yangf80a0542013-10-07 13:02:37 -070012369 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012370 ret = wlan_hdd_validate_context(pHddCtx);
12371 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012373 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070012374 }
12375
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012376 if (pAdapter->request != NULL)
12377 {
12378 if ((pAdapter->request->n_ssids == 1)
12379 && (pAdapter->request->ssids != NULL)
12380 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12381 is_p2p_scan = true;
12382 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012383 /*
12384 * start getting scan results and populate cgf80211 BSS database
12385 */
12386 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12387
12388 /* no scan results */
12389 if (NULL == pResult)
12390 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12392 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012393 wlan_hdd_get_frame_logs(pAdapter,
12394 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012395 return status;
12396 }
12397
12398 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12399
12400 while (pScanResult)
12401 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012402 /*
12403 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12404 * entry already exists in bss data base of cfg80211 for that
12405 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12406 * bss entry instead of cfg80211_inform_bss, But this call expects
12407 * mgmt packet as input. As of now there is no possibility to get
12408 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 * ieee80211_mgmt(probe response) and passing to c
12410 * fg80211_inform_bss_frame.
12411 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012412 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12413 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12414 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012415 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12416 continue; //Skip the non p2p bss entries
12417 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12419 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012420
Jeff Johnson295189b2012-06-20 16:38:30 -070012421
12422 if (NULL == bss_status)
12423 {
12424 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012425 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012426 }
12427 else
12428 {
Yue Maf49ba872013-08-19 12:04:25 -070012429 cfg80211_put_bss(
12430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12431 wiphy,
12432#endif
12433 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012434 }
12435
12436 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12437 }
12438
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012439 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012440 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012441 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012442}
12443
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012444void
12445hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12446{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012447 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012448 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012449} /****** end hddPrintMacAddr() ******/
12450
12451void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012452hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012453{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012454 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012455 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012456 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12457 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12458 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012459} /****** end hddPrintPmkId() ******/
12460
12461//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12462//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12463
12464//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12465//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12466
12467#define dump_bssid(bssid) \
12468 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012469 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12470 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012471 }
12472
12473#define dump_pmkid(pMac, pmkid) \
12474 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012475 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12476 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012477 }
12478
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012479#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012480/*
12481 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12482 * This function is used to notify the supplicant of a new PMKSA candidate.
12483 */
12484int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012485 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012486 int index, bool preauth )
12487{
Jeff Johnsone7245742012-09-05 17:12:55 -070012488#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012489 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012490 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012491
12492 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012493 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012494
12495 if( NULL == pRoamInfo )
12496 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012497 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012498 return -EINVAL;
12499 }
12500
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012501 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12502 {
12503 dump_bssid(pRoamInfo->bssid);
12504 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012505 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012506 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012507#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012508 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012509}
12510#endif //FEATURE_WLAN_LFR
12511
Yue Maef608272013-04-08 23:09:17 -070012512#ifdef FEATURE_WLAN_LFR_METRICS
12513/*
12514 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12515 * 802.11r/LFR metrics reporting function to report preauth initiation
12516 *
12517 */
12518#define MAX_LFR_METRICS_EVENT_LENGTH 100
12519VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12520 tCsrRoamInfo *pRoamInfo)
12521{
12522 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12523 union iwreq_data wrqu;
12524
12525 ENTER();
12526
12527 if (NULL == pAdapter)
12528 {
12529 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12530 return VOS_STATUS_E_FAILURE;
12531 }
12532
12533 /* create the event */
12534 memset(&wrqu, 0, sizeof(wrqu));
12535 memset(metrics_notification, 0, sizeof(metrics_notification));
12536
12537 wrqu.data.pointer = metrics_notification;
12538 wrqu.data.length = scnprintf(metrics_notification,
12539 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12540 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12541
12542 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12543
12544 EXIT();
12545
12546 return VOS_STATUS_SUCCESS;
12547}
12548
12549/*
12550 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12551 * 802.11r/LFR metrics reporting function to report preauth completion
12552 * or failure
12553 */
12554VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12555 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12556{
12557 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12558 union iwreq_data wrqu;
12559
12560 ENTER();
12561
12562 if (NULL == pAdapter)
12563 {
12564 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12565 return VOS_STATUS_E_FAILURE;
12566 }
12567
12568 /* create the event */
12569 memset(&wrqu, 0, sizeof(wrqu));
12570 memset(metrics_notification, 0, sizeof(metrics_notification));
12571
12572 scnprintf(metrics_notification, sizeof(metrics_notification),
12573 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12574 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12575
12576 if (1 == preauth_status)
12577 strncat(metrics_notification, " TRUE", 5);
12578 else
12579 strncat(metrics_notification, " FALSE", 6);
12580
12581 wrqu.data.pointer = metrics_notification;
12582 wrqu.data.length = strlen(metrics_notification);
12583
12584 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12585
12586 EXIT();
12587
12588 return VOS_STATUS_SUCCESS;
12589}
12590
12591/*
12592 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12593 * 802.11r/LFR metrics reporting function to report handover initiation
12594 *
12595 */
12596VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12597 tCsrRoamInfo *pRoamInfo)
12598{
12599 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12600 union iwreq_data wrqu;
12601
12602 ENTER();
12603
12604 if (NULL == pAdapter)
12605 {
12606 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12607 return VOS_STATUS_E_FAILURE;
12608 }
12609
12610 /* create the event */
12611 memset(&wrqu, 0, sizeof(wrqu));
12612 memset(metrics_notification, 0, sizeof(metrics_notification));
12613
12614 wrqu.data.pointer = metrics_notification;
12615 wrqu.data.length = scnprintf(metrics_notification,
12616 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12617 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12618
12619 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12620
12621 EXIT();
12622
12623 return VOS_STATUS_SUCCESS;
12624}
12625#endif
12626
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012627
12628/**
12629 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
12630 * @scan_req: scan request to be checked
12631 *
12632 * Return: true or false
12633 */
12634#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
12635static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12636 cfg80211_scan_request
12637 *scan_req)
12638{
12639 if (!scan_req || !scan_req->wiphy) {
12640 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12641 return false;
12642 }
12643 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
12644 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
12645 return false;
12646 }
12647 return true;
12648}
12649#else
12650static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
12651 cfg80211_scan_request
12652 *scan_req)
12653{
12654 if (!scan_req || !scan_req->wiphy) {
12655 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
12656 return false;
12657 }
12658 return true;
12659}
12660#endif
12661
12662
Jeff Johnson295189b2012-06-20 16:38:30 -070012663/*
12664 * FUNCTION: hdd_cfg80211_scan_done_callback
12665 * scanning callback function, called after finishing scan
12666 *
12667 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012668static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012669 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12670{
12671 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012672 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012674 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 struct cfg80211_scan_request *req = NULL;
12676 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012677 bool aborted = false;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012678#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12679 bool iface_down = false;
12680#endif
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012681 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012682 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012683 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012684
12685 ENTER();
12686
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012688 if (NULL == pHddCtx) {
12689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012690 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012691 }
12692
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12694 if (!(pAdapter->dev->flags & IFF_UP))
12695 {
12696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012697 iface_down = true;
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053012698 }
12699#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012700 pScanInfo = &pHddCtx->scan_info;
12701
Jeff Johnson295189b2012-06-20 16:38:30 -070012702 hddLog(VOS_TRACE_LEVEL_INFO,
12703 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012704 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 __func__, halHandle, pContext, (int) scanId, (int) status);
12706
Kiet Lamac06e2c2013-10-23 16:25:07 +053012707 pScanInfo->mScanPendingCounter = 0;
12708
Jeff Johnson295189b2012-06-20 16:38:30 -070012709 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012710 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 &pScanInfo->scan_req_completion_event,
12712 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012713 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012714 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012715 hddLog(VOS_TRACE_LEVEL_ERROR,
12716 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012717 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012718 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 }
12720
Yue Maef608272013-04-08 23:09:17 -070012721 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012722 {
12723 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012724 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012725 }
12726
12727 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012728 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 {
12730 hddLog(VOS_TRACE_LEVEL_INFO,
12731 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012732 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012733 (int) scanId);
12734 }
12735
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012737 if (!iface_down)
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012738#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012739 {
12740 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
12741 pAdapter);
12742 if (0 > ret)
12743 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053012744 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012745
Jeff Johnson295189b2012-06-20 16:38:30 -070012746 /* If any client wait scan result through WEXT
12747 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012748 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012749 {
12750 /* The other scan request waiting for current scan finish
12751 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012752 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012753 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012754 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012755 }
12756 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012757 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012758 {
12759 struct net_device *dev = pAdapter->dev;
12760 union iwreq_data wrqu;
12761 int we_event;
12762 char *msg;
12763
12764 memset(&wrqu, '\0', sizeof(wrqu));
12765 we_event = SIOCGIWSCAN;
12766 msg = NULL;
12767 wireless_send_event(dev, we_event, &wrqu, msg);
12768 }
12769 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012770 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012771
12772 /* Get the Scan Req */
12773 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053012774 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012775
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012776 /* Scan is no longer pending */
12777 pScanInfo->mScanPending = VOS_FALSE;
12778
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012779 if (!wlan_hdd_cfg80211_validate_scan_req(req))
Jeff Johnson295189b2012-06-20 16:38:30 -070012780 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053012781#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
12783 iface_down ? "up" : "down");
12784#endif
12785
12786 if (pAdapter->dev) {
12787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
12788 pAdapter->dev->name);
12789 }
mukul sharmae7041822015-12-03 15:09:21 +053012790 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070012791 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012792 }
12793
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012794 /* last_scan_timestamp is used to decide if new scan
12795 * is needed or not on station interface. If last station
12796 * scan time and new station scan time is less then
12797 * last_scan_timestamp ; driver will return cached scan.
12798 */
12799 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12800 {
12801 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12802
12803 if ( req->n_channels )
12804 {
12805 for (i = 0; i < req->n_channels ; i++ )
12806 {
12807 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12808 }
12809 /* store no of channel scanned */
12810 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12811 }
12812
12813 }
12814
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012815 /*
12816 * cfg80211_scan_done informing NL80211 about completion
12817 * of scanning
12818 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012819 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12820 {
12821 aborted = true;
12822 }
mukul sharmae7041822015-12-03 15:09:21 +053012823
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012824#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12825 if (!iface_down)
12826#endif
12827 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053012828
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012829 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012830
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012831allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053012832 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
12833 ) && (pHddCtx->spoofMacAddr.isEnabled
12834 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053012835 /* Generate new random mac addr for next scan */
12836 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053012837
12838 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
12839 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053012840 }
12841
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012842 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012843 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012844
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012845 /* Acquire wakelock to handle the case where APP's tries to suspend
12846 * immediatly after the driver gets connect request(i.e after scan)
12847 * from supplicant, this result in app's is suspending and not able
12848 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012849 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012850
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012851#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
12852 if (!iface_down)
12853#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012854#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053012855 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012856#endif
12857
Jeff Johnson295189b2012-06-20 16:38:30 -070012858 EXIT();
12859 return 0;
12860}
12861
12862/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012863 * FUNCTION: hdd_isConnectionInProgress
12864 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012865 *
12866 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012867v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012868{
12869 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12870 hdd_station_ctx_t *pHddStaCtx = NULL;
12871 hdd_adapter_t *pAdapter = NULL;
12872 VOS_STATUS status = 0;
12873 v_U8_t staId = 0;
12874 v_U8_t *staMac = NULL;
12875
12876 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12877
12878 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12879 {
12880 pAdapter = pAdapterNode->pAdapter;
12881
12882 if( pAdapter )
12883 {
12884 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012885 "%s: Adapter with device mode %s (%d) exists",
12886 __func__, hdd_device_modetoString(pAdapter->device_mode),
12887 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012888 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012889 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12890 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12891 (eConnectionState_Connecting ==
12892 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12893 {
12894 hddLog(VOS_TRACE_LEVEL_ERROR,
12895 "%s: %p(%d) Connection is in progress", __func__,
12896 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12897 return VOS_TRUE;
12898 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012899 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012900 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012901 {
12902 hddLog(VOS_TRACE_LEVEL_ERROR,
12903 "%s: %p(%d) Reassociation is in progress", __func__,
12904 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12905 return VOS_TRUE;
12906 }
12907 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012908 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12909 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012910 {
12911 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12912 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012913 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012914 {
12915 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12916 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012917 "%s: client " MAC_ADDRESS_STR
12918 " is in the middle of WPS/EAPOL exchange.", __func__,
12919 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012920 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012921 }
12922 }
12923 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12924 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12925 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012926 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12927 ptSapContext pSapCtx = NULL;
12928 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12929 if(pSapCtx == NULL){
12930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12931 FL("psapCtx is NULL"));
12932 return VOS_FALSE;
12933 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012934 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12935 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012936 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12937 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012938 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012939 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012940
12941 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012942 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12943 "middle of WPS/EAPOL exchange.", __func__,
12944 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012945 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012946 }
12947 }
12948 }
12949 }
12950 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12951 pAdapterNode = pNext;
12952 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012953 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012954}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012955
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053012956/**
12957 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
12958 * to the Scan request
12959 * @scanRequest: Pointer to the csr scan request
12960 * @request: Pointer to the scan request from supplicant
12961 *
12962 * Return: None
12963 */
12964#ifdef CFG80211_SCAN_BSSID
12965static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12966 struct cfg80211_scan_request *request)
12967{
12968 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
12969}
12970#else
12971static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
12972 struct cfg80211_scan_request *request)
12973{
12974}
12975#endif
12976
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012977/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012978 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012979 * this scan respond to scan trigger and update cfg80211 scan database
12980 * later, scan dump command can be used to recieve scan results
12981 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012982int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012983#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12984 struct net_device *dev,
12985#endif
12986 struct cfg80211_scan_request *request)
12987{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012988 hdd_adapter_t *pAdapter = NULL;
12989 hdd_context_t *pHddCtx = NULL;
12990 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012991 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012992 tCsrScanRequest scanRequest;
12993 tANI_U8 *channelList = NULL, i;
12994 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012995 int status;
12996 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012997 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012998 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012999 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013000 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013001
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
13003 struct net_device *dev = NULL;
13004 if (NULL == request)
13005 {
13006 hddLog(VOS_TRACE_LEVEL_ERROR,
13007 "%s: scan req param null", __func__);
13008 return -EINVAL;
13009 }
13010 dev = request->wdev->netdev;
13011#endif
13012
13013 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13014 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
13015 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13016
Jeff Johnson295189b2012-06-20 16:38:30 -070013017 ENTER();
13018
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013019 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13020 __func__, hdd_device_modetoString(pAdapter->device_mode),
13021 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013022
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013023 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013024 if (0 != status)
13025 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013026 return status;
13027 }
13028
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013029 if (NULL == pwextBuf)
13030 {
13031 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
13032 __func__);
13033 return -EIO;
13034 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013035 cfg_param = pHddCtx->cfg_ini;
13036 pScanInfo = &pHddCtx->scan_info;
13037
Jeff Johnson295189b2012-06-20 16:38:30 -070013038#ifdef WLAN_BTAMP_FEATURE
13039 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013040 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070013041 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013042 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013043 "%s: No scanning when AMP is on", __func__);
13044 return -EOPNOTSUPP;
13045 }
13046#endif
13047 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013048 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013050 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013051 "%s: Not scanning on device_mode = %s (%d)",
13052 __func__, hdd_device_modetoString(pAdapter->device_mode),
13053 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013054 return -EOPNOTSUPP;
13055 }
13056
13057 if (TRUE == pScanInfo->mScanPending)
13058 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013059 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
13060 {
13061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
13062 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013063 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 }
13065
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053013066 // Don't allow scan if PNO scan is going on.
13067 if (pHddCtx->isPnoEnable)
13068 {
13069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13070 FL("pno scan in progress"));
13071 return -EBUSY;
13072 }
13073
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013074 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070013075 //Channel and action frame is pending
13076 //Otherwise Cancel Remain On Channel and allow Scan
13077 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013078 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070013079 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053013080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070013081 return -EBUSY;
13082 }
13083
Jeff Johnson295189b2012-06-20 16:38:30 -070013084 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
13085 {
13086 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080013087 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013088 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013089 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013090 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
13091 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013092 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 "%s: MAX TM Level Scan not allowed", __func__);
13094 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013095 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070013096 }
13097 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
13098
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013099 /* Check if scan is allowed at this point of time.
13100 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053013101 if (TRUE == pHddCtx->btCoexModeSet)
13102 {
13103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13104 FL("BTCoex Mode operation in progress"));
13105 return -EBUSY;
13106 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053013107 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013108 {
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Scan not allowed"));
13110 if (SCAN_ABORT_THRESHOLD < pHddCtx->con_scan_abort_cnt) {
13111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13112 FL("Triggering SSR, SSR status = %d"), status);
13113 vos_wlanRestart();
13114 }
13115 else
13116 pHddCtx->con_scan_abort_cnt++;
13117
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080013118 return -EBUSY;
13119 }
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053013120 pHddCtx->con_scan_abort_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013121
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 vos_mem_zero( &scanRequest, sizeof(scanRequest));
13123
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013124 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
13125 * Becasue of this, driver is assuming that this is not wildcard scan and so
13126 * is not aging out the scan results.
13127 */
13128 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013130 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013131 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013132
13133 if ((request->ssids) && (0 < request->n_ssids))
13134 {
13135 tCsrSSIDInfo *SsidInfo;
13136 int j;
13137 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
13138 /* Allocate num_ssid tCsrSSIDInfo structure */
13139 SsidInfo = scanRequest.SSIDs.SSIDList =
13140 ( tCsrSSIDInfo *)vos_mem_malloc(
13141 request->n_ssids*sizeof(tCsrSSIDInfo));
13142
13143 if(NULL == scanRequest.SSIDs.SSIDList)
13144 {
13145 hddLog(VOS_TRACE_LEVEL_ERROR,
13146 "%s: memory alloc failed SSIDInfo buffer", __func__);
13147 return -ENOMEM;
13148 }
13149
13150 /* copy all the ssid's and their length */
13151 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
13152 {
13153 /* get the ssid length */
13154 SsidInfo->SSID.length = request->ssids[j].ssid_len;
13155 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
13156 SsidInfo->SSID.length);
13157 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
13158 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
13159 j, SsidInfo->SSID.ssId);
13160 }
13161 /* set the scan type to active */
13162 scanRequest.scanType = eSIR_ACTIVE_SCAN;
13163 }
13164 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013165 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053013166 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13167 TRACE_CODE_HDD_CFG80211_SCAN,
13168 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070013169 /* set the scan type to active */
13170 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013172 else
13173 {
13174 /*Set the scan type to default type, in this case it is ACTIVE*/
13175 scanRequest.scanType = pScanInfo->scan_mode;
13176 }
13177 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
13178 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070013179
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053013180 csr_scan_request_assign_bssid(&scanRequest, request);
13181
Jeff Johnson295189b2012-06-20 16:38:30 -070013182 /* set BSSType to default type */
13183 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
13184
13185 /*TODO: scan the requested channels only*/
13186
13187 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013188 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070013189 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013190 hddLog(VOS_TRACE_LEVEL_WARN,
13191 "No of Scan Channels exceeded limit: %d", request->n_channels);
13192 request->n_channels = MAX_CHANNEL;
13193 }
13194
13195 hddLog(VOS_TRACE_LEVEL_INFO,
13196 "No of Scan Channels: %d", request->n_channels);
13197
13198
13199 if( request->n_channels )
13200 {
13201 char chList [(request->n_channels*5)+1];
13202 int len;
13203 channelList = vos_mem_malloc( request->n_channels );
13204 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053013205 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013206 hddLog(VOS_TRACE_LEVEL_ERROR,
13207 "%s: memory alloc failed channelList", __func__);
13208 status = -ENOMEM;
13209 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053013210 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013211
13212 for( i = 0, len = 0; i < request->n_channels ; i++ )
13213 {
13214 channelList[i] = request->channels[i]->hw_value;
13215 len += snprintf(chList+len, 5, "%d ", channelList[i]);
13216 }
13217
Nirav Shah20ac06f2013-12-12 18:14:06 +053013218 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013219 "Channel-List: %s ", chList);
13220 }
c_hpothu53512302014-04-15 18:49:53 +053013221
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013222 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
13223 scanRequest.ChannelInfo.ChannelList = channelList;
13224
13225 /* set requestType to full scan */
13226 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
13227
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013228 /* if there is back to back scan happening in driver with in
13229 * nDeferScanTimeInterval interval driver should defer new scan request
13230 * and should provide last cached scan results instead of new channel list.
13231 * This rule is not applicable if scan is p2p scan.
13232 * This condition will work only in case when last request no of channels
13233 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053013234 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053013235 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013236 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013237
Sushant Kaushik86592172015-04-27 16:35:03 +053013238 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
13239 /* if wps ie is NULL , then only defer scan */
13240 if ( pWpsIe == NULL &&
13241 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013242 {
13243 if ( pScanInfo->last_scan_timestamp !=0 &&
13244 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13245 {
13246 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13247 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13248 vos_mem_compare(pScanInfo->last_scan_channelList,
13249 channelList, pScanInfo->last_scan_numChannels))
13250 {
13251 hddLog(VOS_TRACE_LEVEL_WARN,
13252 " New and old station scan time differ is less then %u",
13253 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13254
13255 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013256 pAdapter);
13257
Agarwal Ashish57e84372014-12-05 18:26:53 +053013258 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013259 "Return old cached scan as all channels and no of channels are same");
13260
Agarwal Ashish57e84372014-12-05 18:26:53 +053013261 if (0 > ret)
13262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013263
Agarwal Ashish57e84372014-12-05 18:26:53 +053013264 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013265
13266 status = eHAL_STATUS_SUCCESS;
13267 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013268 }
13269 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013270 }
13271
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013272 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13273 * search (Flush on both full scan and social scan but not on single
13274 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13275 */
13276
13277 /* Supplicant does single channel scan after 8-way handshake
13278 * and in that case driver shoudnt flush scan results. If
13279 * driver flushes the scan results here and unfortunately if
13280 * the AP doesnt respond to our probe req then association
13281 * fails which is not desired
13282 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013283 if ((request->n_ssids == 1)
13284 && (request->ssids != NULL)
13285 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13286 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013287
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013288 if( is_p2p_scan ||
13289 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013290 {
13291 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13292 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13293 pAdapter->sessionId );
13294 }
13295
13296 if( request->ie_len )
13297 {
13298 /* save this for future association (join requires this) */
13299 /*TODO: Array needs to be converted to dynamic allocation,
13300 * as multiple ie.s can be sent in cfg80211_scan_request structure
13301 * CR 597966
13302 */
13303 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13304 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13305 pScanInfo->scanAddIE.length = request->ie_len;
13306
13307 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13308 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13309 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013311 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013312 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013313 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13314 memcpy( pwextBuf->roamProfile.addIEScan,
13315 request->ie, request->ie_len);
13316 }
13317 else
13318 {
13319 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13320 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013321 }
13322
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013323 }
13324 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13325 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13326
13327 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13328 request->ie_len);
13329 if (pP2pIe != NULL)
13330 {
13331#ifdef WLAN_FEATURE_P2P_DEBUG
13332 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13333 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13334 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013335 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013336 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13337 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13338 "Go nego completed to Connection is started");
13339 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13340 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013341 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013342 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13343 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013344 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013345 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13346 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13347 "Disconnected state to Connection is started");
13348 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13349 "for 4way Handshake");
13350 }
13351#endif
13352
13353 /* no_cck will be set during p2p find to disable 11b rates */
13354 if(TRUE == request->no_cck)
13355 {
13356 hddLog(VOS_TRACE_LEVEL_INFO,
13357 "%s: This is a P2P Search", __func__);
13358 scanRequest.p2pSearch = 1;
13359
13360 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013361 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013362 /* set requestType to P2P Discovery */
13363 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13364 }
13365
13366 /*
13367 Skip Dfs Channel in case of P2P Search
13368 if it is set in ini file
13369 */
13370 if(cfg_param->skipDfsChnlInP2pSearch)
13371 {
13372 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013373 }
13374 else
13375 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013376 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013377 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013378
Agarwal Ashish4f616132013-12-30 23:32:50 +053013379 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 }
13381 }
13382
13383 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13384
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013385#ifdef FEATURE_WLAN_TDLS
13386 /* if tdls disagree scan right now, return immediately.
13387 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13388 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13389 */
13390 status = wlan_hdd_tdls_scan_callback (pAdapter,
13391 wiphy,
13392#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13393 dev,
13394#endif
13395 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013396 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013397 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053013398 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013399 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13400 "scan rejected %d", __func__, status);
13401 else
13402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13403 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053013404 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053013405 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013406 }
13407#endif
13408
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013409 /* acquire the wakelock to avoid the apps suspend during the scan. To
13410 * address the following issues.
13411 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13412 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13413 * for long time, this result in apps running at full power for long time.
13414 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13415 * be stuck in full power because of resume BMPS
13416 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013417 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013418
Nirav Shah20ac06f2013-12-12 18:14:06 +053013419 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13420 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013421 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13422 scanRequest.requestType, scanRequest.scanType,
13423 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013424 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13425
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053013426 if (pHddCtx->spoofMacAddr.isEnabled &&
13427 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053013428 {
13429 hddLog(VOS_TRACE_LEVEL_INFO,
13430 "%s: MAC Spoofing enabled for current scan", __func__);
13431 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13432 * to fill TxBds for probe request during current scan
13433 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013434 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013435 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013436
13437 if(status != VOS_STATUS_SUCCESS)
13438 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013439 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013440 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013441#ifdef FEATURE_WLAN_TDLS
13442 wlan_hdd_tdls_scan_done_callback(pAdapter);
13443#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013444 goto free_mem;
13445 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013446 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013447 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013448 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013449 pAdapter->sessionId, &scanRequest, &scanId,
13450 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013451
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 if (eHAL_STATUS_SUCCESS != status)
13453 {
13454 hddLog(VOS_TRACE_LEVEL_ERROR,
13455 "%s: sme_ScanRequest returned error %d", __func__, status);
13456 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013457 if(eHAL_STATUS_RESOURCES == status)
13458 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13460 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013461 status = -EBUSY;
13462 } else {
13463 status = -EIO;
13464 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013465 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013466
13467#ifdef FEATURE_WLAN_TDLS
13468 wlan_hdd_tdls_scan_done_callback(pAdapter);
13469#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013470 goto free_mem;
13471 }
13472
13473 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013474 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013475 pAdapter->request = request;
13476 pScanInfo->scanId = scanId;
13477
13478 complete(&pScanInfo->scan_req_completion_event);
13479
13480free_mem:
13481 if( scanRequest.SSIDs.SSIDList )
13482 {
13483 vos_mem_free(scanRequest.SSIDs.SSIDList);
13484 }
13485
13486 if( channelList )
13487 vos_mem_free( channelList );
13488
13489 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013490 return status;
13491}
13492
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013493int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13494#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13495 struct net_device *dev,
13496#endif
13497 struct cfg80211_scan_request *request)
13498{
13499 int ret;
13500
13501 vos_ssr_protect(__func__);
13502 ret = __wlan_hdd_cfg80211_scan(wiphy,
13503#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13504 dev,
13505#endif
13506 request);
13507 vos_ssr_unprotect(__func__);
13508
13509 return ret;
13510}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013511
13512void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13513{
13514 v_U8_t iniDot11Mode =
13515 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13516 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13517
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013518 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13519 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013520 switch ( iniDot11Mode )
13521 {
13522 case eHDD_DOT11_MODE_AUTO:
13523 case eHDD_DOT11_MODE_11ac:
13524 case eHDD_DOT11_MODE_11ac_ONLY:
13525#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013526 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13527 sme_IsFeatureSupportedByFW(DOT11AC) )
13528 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13529 else
13530 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013531#else
13532 hddDot11Mode = eHDD_DOT11_MODE_11n;
13533#endif
13534 break;
13535 case eHDD_DOT11_MODE_11n:
13536 case eHDD_DOT11_MODE_11n_ONLY:
13537 hddDot11Mode = eHDD_DOT11_MODE_11n;
13538 break;
13539 default:
13540 hddDot11Mode = iniDot11Mode;
13541 break;
13542 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013543#ifdef WLAN_FEATURE_AP_HT40_24G
13544 if (operationChannel > SIR_11B_CHANNEL_END)
13545#endif
13546 {
13547 /* This call decides required channel bonding mode */
13548 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013549 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13550 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013551 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013552}
13553
Jeff Johnson295189b2012-06-20 16:38:30 -070013554/*
13555 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013556 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013558int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013559 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13560 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013561{
13562 int status = 0;
13563 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013564 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013565 v_U32_t roamId;
13566 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013568 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013569
13570 ENTER();
13571
13572 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013573 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13574
13575 status = wlan_hdd_validate_context(pHddCtx);
13576 if (status)
13577 {
Yue Mae36e3552014-03-05 17:06:20 -080013578 return status;
13579 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013580
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13582 {
13583 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13584 return -EINVAL;
13585 }
13586
13587 pRoamProfile = &pWextState->roamProfile;
13588
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013589 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013591 hdd_station_ctx_t *pHddStaCtx;
13592 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013593
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013594 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13595
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013596 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013597 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13598 {
13599 /*QoS not enabled in cfg file*/
13600 pRoamProfile->uapsd_mask = 0;
13601 }
13602 else
13603 {
13604 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013605 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13607 }
13608
13609 pRoamProfile->SSIDs.numOfSSIDs = 1;
13610 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13611 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013612 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013613 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13614 ssid, ssid_len);
13615
13616 if (bssid)
13617 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013618 pValidBssid = bssid;
13619 }
13620 else if (bssid_hint)
13621 {
13622 pValidBssid = bssid_hint;
13623 }
13624 if (pValidBssid)
13625 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013626 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013627 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013628 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013629 /* Save BSSID in seperate variable as well, as RoamProfile
13630 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013631 case of join failure we should send valid BSSID to supplicant
13632 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013633 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 WNI_CFG_BSSID_LEN);
13635 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013636 else
13637 {
13638 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13639 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013640
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013641 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13642 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013643 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13644 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013645 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013646 /*set gen ie*/
13647 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13648 /*set auth*/
13649 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13650 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013651#ifdef FEATURE_WLAN_WAPI
13652 if (pAdapter->wapi_info.nWapiMode)
13653 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013654 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013655 switch (pAdapter->wapi_info.wapiAuthMode)
13656 {
13657 case WAPI_AUTH_MODE_PSK:
13658 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013659 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013660 pAdapter->wapi_info.wapiAuthMode);
13661 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13662 break;
13663 }
13664 case WAPI_AUTH_MODE_CERT:
13665 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013666 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013667 pAdapter->wapi_info.wapiAuthMode);
13668 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13669 break;
13670 }
13671 } // End of switch
13672 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13673 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13674 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013675 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 pRoamProfile->AuthType.numEntries = 1;
13677 pRoamProfile->EncryptionType.numEntries = 1;
13678 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13679 pRoamProfile->mcEncryptionType.numEntries = 1;
13680 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13681 }
13682 }
13683#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013684#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013685 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013686 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13687 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13688 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013689 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13690 sizeof (tSirGtkOffloadParams));
13691 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013692 }
13693#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 pRoamProfile->csrPersona = pAdapter->device_mode;
13695
Jeff Johnson32d95a32012-09-10 13:15:23 -070013696 if( operatingChannel )
13697 {
13698 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13699 pRoamProfile->ChannelInfo.numOfChannels = 1;
13700 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013701 else
13702 {
13703 pRoamProfile->ChannelInfo.ChannelList = NULL;
13704 pRoamProfile->ChannelInfo.numOfChannels = 0;
13705 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013706 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13707 {
13708 hdd_select_cbmode(pAdapter,operatingChannel);
13709 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013710
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013711 /*
13712 * Change conn_state to connecting before sme_RoamConnect(),
13713 * because sme_RoamConnect() has a direct path to call
13714 * hdd_smeRoamCallback(), which will change the conn_state
13715 * If direct path, conn_state will be accordingly changed
13716 * to NotConnected or Associated by either
13717 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13718 * in sme_RoamCallback()
13719 * if sme_RomConnect is to be queued,
13720 * Connecting state will remain until it is completed.
13721 * If connection state is not changed,
13722 * connection state will remain in eConnectionState_NotConnected state.
13723 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13724 * if conn state is eConnectionState_NotConnected.
13725 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13726 * informed of connect result indication which is an issue.
13727 */
13728
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013729 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13730 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013731 {
13732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013733 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013734 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13735 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013736 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013737 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 pAdapter->sessionId, pRoamProfile, &roamId);
13739
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013740 if ((eHAL_STATUS_SUCCESS != status) &&
13741 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13742 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013743
13744 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013745 hddLog(VOS_TRACE_LEVEL_ERROR,
13746 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13747 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013748 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013749 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013750 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013751 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013752
13753 pRoamProfile->ChannelInfo.ChannelList = NULL;
13754 pRoamProfile->ChannelInfo.numOfChannels = 0;
13755
Jeff Johnson295189b2012-06-20 16:38:30 -070013756 }
13757 else
13758 {
13759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13760 return -EINVAL;
13761 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013762 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013763 return status;
13764}
13765
13766/*
13767 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13768 * This function is used to set the authentication type (OPEN/SHARED).
13769 *
13770 */
13771static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13772 enum nl80211_auth_type auth_type)
13773{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013774 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13776
13777 ENTER();
13778
13779 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013780 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013782 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013783 hddLog(VOS_TRACE_LEVEL_INFO,
13784 "%s: set authentication type to AUTOSWITCH", __func__);
13785 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13786 break;
13787
13788 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013789#ifdef WLAN_FEATURE_VOWIFI_11R
13790 case NL80211_AUTHTYPE_FT:
13791#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013792 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013793 "%s: set authentication type to OPEN", __func__);
13794 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13795 break;
13796
13797 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013798 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 "%s: set authentication type to SHARED", __func__);
13800 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13801 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013802#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013803 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013804 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013805 "%s: set authentication type to CCKM WPA", __func__);
13806 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13807 break;
13808#endif
13809
13810
13811 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013812 hddLog(VOS_TRACE_LEVEL_ERROR,
13813 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013814 auth_type);
13815 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13816 return -EINVAL;
13817 }
13818
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013819 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 pHddStaCtx->conn_info.authType;
13821 return 0;
13822}
13823
13824/*
13825 * FUNCTION: wlan_hdd_set_akm_suite
13826 * This function is used to set the key mgmt type(PSK/8021x).
13827 *
13828 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013829static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013830 u32 key_mgmt
13831 )
13832{
13833 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13834 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013835 /* Should be in ieee802_11_defs.h */
13836#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13837#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013838 /*set key mgmt type*/
13839 switch(key_mgmt)
13840 {
13841 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013842 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013843#ifdef WLAN_FEATURE_VOWIFI_11R
13844 case WLAN_AKM_SUITE_FT_PSK:
13845#endif
13846 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 __func__);
13848 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13849 break;
13850
13851 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013852 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013853#ifdef WLAN_FEATURE_VOWIFI_11R
13854 case WLAN_AKM_SUITE_FT_8021X:
13855#endif
13856 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 __func__);
13858 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13859 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013860#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013861#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13862#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13863 case WLAN_AKM_SUITE_CCKM:
13864 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13865 __func__);
13866 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13867 break;
13868#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013869#ifndef WLAN_AKM_SUITE_OSEN
13870#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13871 case WLAN_AKM_SUITE_OSEN:
13872 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13873 __func__);
13874 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13875 break;
13876#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013877
13878 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 __func__, key_mgmt);
13881 return -EINVAL;
13882
13883 }
13884 return 0;
13885}
13886
13887/*
13888 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013889 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 * (NONE/WEP40/WEP104/TKIP/CCMP).
13891 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013892static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13893 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 bool ucast
13895 )
13896{
13897 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013898 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013899 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13900
13901 ENTER();
13902
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013903 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013904 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013905 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 __func__, cipher);
13907 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13908 }
13909 else
13910 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013911
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013913 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 {
13915 case IW_AUTH_CIPHER_NONE:
13916 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13917 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013918
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013920 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013922
Jeff Johnson295189b2012-06-20 16:38:30 -070013923 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013924 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013926
Jeff Johnson295189b2012-06-20 16:38:30 -070013927 case WLAN_CIPHER_SUITE_TKIP:
13928 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13929 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013930
Jeff Johnson295189b2012-06-20 16:38:30 -070013931 case WLAN_CIPHER_SUITE_CCMP:
13932 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13933 break;
13934#ifdef FEATURE_WLAN_WAPI
13935 case WLAN_CIPHER_SUITE_SMS4:
13936 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13937 break;
13938#endif
13939
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013940#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 case WLAN_CIPHER_SUITE_KRK:
13942 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13943 break;
13944#endif
13945 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 __func__, cipher);
13948 return -EOPNOTSUPP;
13949 }
13950 }
13951
13952 if (ucast)
13953 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013954 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013955 __func__, encryptionType);
13956 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13957 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013958 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013959 encryptionType;
13960 }
13961 else
13962 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013963 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013964 __func__, encryptionType);
13965 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13966 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13967 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13968 }
13969
13970 return 0;
13971}
13972
13973
13974/*
13975 * FUNCTION: wlan_hdd_cfg80211_set_ie
13976 * This function is used to parse WPA/RSN IE's.
13977 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013978int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13980 const u8 *ie,
13981#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013982 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013983#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013984 size_t ie_len
13985 )
13986{
13987 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13989 const u8 *genie = ie;
13990#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013992#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013993 v_U16_t remLen = ie_len;
13994#ifdef FEATURE_WLAN_WAPI
13995 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13996 u16 *tmp;
13997 v_U16_t akmsuiteCount;
13998 int *akmlist;
13999#endif
14000 ENTER();
14001
14002 /* clear previous assocAddIE */
14003 pWextState->assocAddIE.length = 0;
14004 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014005 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014006
14007 while (remLen >= 2)
14008 {
14009 v_U16_t eLen = 0;
14010 v_U8_t elementId;
14011 elementId = *genie++;
14012 eLen = *genie++;
14013 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014014
Arif Hussain6d2a3322013-11-17 19:50:10 -080014015 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014017
14018 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070014019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014020 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014021 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 -070014022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014023 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014024 "%s: Invalid WPA IE", __func__);
14025 return -EINVAL;
14026 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014027 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070014028 {
14029 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014030 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014031 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014032
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014033 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014034 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014035 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
14036 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 VOS_ASSERT(0);
14038 return -ENOMEM;
14039 }
14040 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14041 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14042 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014043
Jeff Johnson295189b2012-06-20 16:38:30 -070014044 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
14045 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14046 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14047 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014048 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
14049 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014050 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
14051 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14052 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
14053 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
14054 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
14055 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014056 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053014057 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070014058 {
14059 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014060 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014061 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014062
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014063 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014064 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014065 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14066 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014067 VOS_ASSERT(0);
14068 return -ENOMEM;
14069 }
14070 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
14071 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14072 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014073
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14075 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14076 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014077#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014078 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
14079 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014080 /*Consider WFD IE, only for P2P Client */
14081 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14082 {
14083 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014084 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070014085 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014086
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014087 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014089 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14090 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 VOS_ASSERT(0);
14092 return -ENOMEM;
14093 }
14094 // WFD IE is saved to Additional IE ; it should be accumulated to handle
14095 // WPS IE + P2P IE + WFD IE
14096 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14097 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014098
Jeff Johnson295189b2012-06-20 16:38:30 -070014099 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14100 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14101 }
14102#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014103 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014104 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014105 HS20_OUI_TYPE_SIZE)) )
14106 {
14107 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014108 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014109 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014110
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014111 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014112 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014113 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14114 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014115 VOS_ASSERT(0);
14116 return -ENOMEM;
14117 }
14118 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14119 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014120
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070014121 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14122 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14123 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014124 /* Appending OSEN Information Element in Assiciation Request */
14125 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
14126 OSEN_OUI_TYPE_SIZE)) )
14127 {
14128 v_U16_t curAddIELen = pWextState->assocAddIE.length;
14129 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
14130 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014131
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014132 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070014133 {
14134 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14135 "Need bigger buffer space");
14136 VOS_ASSERT(0);
14137 return -ENOMEM;
14138 }
14139 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14140 pWextState->assocAddIE.length += eLen + 2;
14141
14142 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
14143 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14144 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14145 }
14146
Abhishek Singh4322e622015-06-10 15:42:54 +053014147 /* Update only for WPA IE */
14148 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
14149 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014150
14151 /* populating as ADDIE in beacon frames */
14152 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014153 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014154 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
14155 {
14156 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14157 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
14158 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14159 {
14160 hddLog(LOGE,
14161 "Coldn't pass "
14162 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
14163 }
14164 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
14165 else
14166 hddLog(LOGE,
14167 "Could not pass on "
14168 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
14169
14170 /* IBSS mode doesn't contain params->proberesp_ies still
14171 beaconIE's need to be populated in probe response frames */
14172 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
14173 {
14174 u16 rem_probe_resp_ie_len = eLen + 2;
14175 u8 probe_rsp_ie_len[3] = {0};
14176 u8 counter = 0;
14177
14178 /* Check Probe Resp Length if it is greater then 255 then
14179 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
14180 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
14181 not able Store More then 255 bytes into One Variable */
14182
14183 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
14184 {
14185 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
14186 {
14187 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
14188 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
14189 }
14190 else
14191 {
14192 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
14193 rem_probe_resp_ie_len = 0;
14194 }
14195 }
14196
14197 rem_probe_resp_ie_len = 0;
14198
14199 if (probe_rsp_ie_len[0] > 0)
14200 {
14201 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14202 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
14203 (tANI_U8*)(genie - 2),
14204 probe_rsp_ie_len[0], NULL,
14205 eANI_BOOLEAN_FALSE)
14206 == eHAL_STATUS_FAILURE)
14207 {
14208 hddLog(LOGE,
14209 "Could not pass"
14210 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
14211 }
14212 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
14213 }
14214
14215 if (probe_rsp_ie_len[1] > 0)
14216 {
14217 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14218 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
14219 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14220 probe_rsp_ie_len[1], NULL,
14221 eANI_BOOLEAN_FALSE)
14222 == eHAL_STATUS_FAILURE)
14223 {
14224 hddLog(LOGE,
14225 "Could not pass"
14226 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
14227 }
14228 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
14229 }
14230
14231 if (probe_rsp_ie_len[2] > 0)
14232 {
14233 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
14234 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
14235 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
14236 probe_rsp_ie_len[2], NULL,
14237 eANI_BOOLEAN_FALSE)
14238 == eHAL_STATUS_FAILURE)
14239 {
14240 hddLog(LOGE,
14241 "Could not pass"
14242 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14243 }
14244 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14245 }
14246
14247 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14248 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14249 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14250 {
14251 hddLog(LOGE,
14252 "Could not pass"
14253 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14254 }
14255 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014256 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014257 break;
14258 case DOT11F_EID_RSN:
14259 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14260 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14261 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14262 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14263 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14264 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014265
Abhishek Singhb16f3562016-01-20 11:08:32 +053014266 /* Appending extended capabilities with Interworking or
14267 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053014268 *
14269 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053014270 * interworkingService or bsstransition bit is set to 1.
14271 * Driver is only interested in interworkingService and
14272 * bsstransition capability from supplicant.
14273 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053014274 * required from supplicat, it needs to be handled while
14275 * sending Assoc Req in LIM.
14276 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014277 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014278 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014279 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014280 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014281 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014282
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014283 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014284 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014285 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14286 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014287 VOS_ASSERT(0);
14288 return -ENOMEM;
14289 }
14290 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14291 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014292
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014293 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14294 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14295 break;
14296 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014297#ifdef FEATURE_WLAN_WAPI
14298 case WLAN_EID_WAPI:
14299 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014300 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014301 pAdapter->wapi_info.nWapiMode);
14302 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014303 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014304 akmsuiteCount = WPA_GET_LE16(tmp);
14305 tmp = tmp + 1;
14306 akmlist = (int *)(tmp);
14307 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14308 {
14309 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14310 }
14311 else
14312 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014313 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014314 VOS_ASSERT(0);
14315 return -EINVAL;
14316 }
14317
14318 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14319 {
14320 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014321 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014322 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014323 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014324 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014325 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014327 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014328 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14329 }
14330 break;
14331#endif
14332 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014333 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014334 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014335 /* when Unknown IE is received we should break and continue
14336 * to the next IE in the buffer instead we were returning
14337 * so changing this to break */
14338 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 }
14340 genie += eLen;
14341 remLen -= eLen;
14342 }
14343 EXIT();
14344 return 0;
14345}
14346
14347/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014348 * FUNCTION: hdd_isWPAIEPresent
14349 * Parse the received IE to find the WPA IE
14350 *
14351 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014352static bool hdd_isWPAIEPresent(
14353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14354 const u8 *ie,
14355#else
14356 u8 *ie,
14357#endif
14358 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014359{
14360 v_U8_t eLen = 0;
14361 v_U16_t remLen = ie_len;
14362 v_U8_t elementId = 0;
14363
14364 while (remLen >= 2)
14365 {
14366 elementId = *ie++;
14367 eLen = *ie++;
14368 remLen -= 2;
14369 if (eLen > remLen)
14370 {
14371 hddLog(VOS_TRACE_LEVEL_ERROR,
14372 "%s: IE length is wrong %d", __func__, eLen);
14373 return FALSE;
14374 }
14375 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14376 {
14377 /* OUI - 0x00 0X50 0XF2
14378 WPA Information Element - 0x01
14379 WPA version - 0x01*/
14380 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14381 return TRUE;
14382 }
14383 ie += eLen;
14384 remLen -= eLen;
14385 }
14386 return FALSE;
14387}
14388
14389/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014390 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014391 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014392 * parameters during connect operation.
14393 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014394int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014395 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014396 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014397{
14398 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014399 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 ENTER();
14401
14402 /*set wpa version*/
14403 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14404
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014405 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014406 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014407 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014408 {
14409 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14410 }
14411 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14412 {
14413 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14414 }
14415 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014416
14417 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014418 pWextState->wpaVersion);
14419
14420 /*set authentication type*/
14421 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14422
14423 if (0 > status)
14424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014425 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014426 "%s: failed to set authentication type ", __func__);
14427 return status;
14428 }
14429
14430 /*set key mgmt type*/
14431 if (req->crypto.n_akm_suites)
14432 {
14433 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14434 if (0 > status)
14435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014437 __func__);
14438 return status;
14439 }
14440 }
14441
14442 /*set pairwise cipher type*/
14443 if (req->crypto.n_ciphers_pairwise)
14444 {
14445 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14446 req->crypto.ciphers_pairwise[0], true);
14447 if (0 > status)
14448 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014449 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014450 "%s: failed to set unicast cipher type", __func__);
14451 return status;
14452 }
14453 }
14454 else
14455 {
14456 /*Reset previous cipher suite to none*/
14457 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14458 if (0 > status)
14459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014460 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014461 "%s: failed to set unicast cipher type", __func__);
14462 return status;
14463 }
14464 }
14465
14466 /*set group cipher type*/
14467 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14468 false);
14469
14470 if (0 > status)
14471 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014472 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014473 __func__);
14474 return status;
14475 }
14476
Chet Lanctot186b5732013-03-18 10:26:30 -070014477#ifdef WLAN_FEATURE_11W
14478 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14479#endif
14480
Jeff Johnson295189b2012-06-20 16:38:30 -070014481 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14482 if (req->ie_len)
14483 {
14484 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14485 if ( 0 > status)
14486 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014488 __func__);
14489 return status;
14490 }
14491 }
14492
14493 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014494 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014495 {
14496 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14497 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14498 )
14499 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014500 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014501 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014504 __func__);
14505 return -EOPNOTSUPP;
14506 }
14507 else
14508 {
14509 u8 key_len = req->key_len;
14510 u8 key_idx = req->key_idx;
14511
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014512 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 && (CSR_MAX_NUM_KEY > key_idx)
14514 )
14515 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014516 hddLog(VOS_TRACE_LEVEL_INFO,
14517 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014518 __func__, key_idx, key_len);
14519 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014520 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014522 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014523 (u8)key_len;
14524 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14525 }
14526 }
14527 }
14528 }
14529
14530 return status;
14531}
14532
14533/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014534 * FUNCTION: wlan_hdd_try_disconnect
14535 * This function is used to disconnect from previous
14536 * connection
14537 */
14538static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14539{
14540 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014541 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014542 hdd_station_ctx_t *pHddStaCtx;
14543 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014544 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014545
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014546 ret = wlan_hdd_validate_context(pHddCtx);
14547 if (0 != ret)
14548 {
14549 return ret;
14550 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014551 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14552
14553 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14554
14555 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14556 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053014557 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014558 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14559 {
Abhishek Singh19a7dd92015-12-30 16:31:51 +053014560 spin_lock_bh(&pAdapter->lock_for_active_session);
14561 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14562 {
14563 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14564 }
14565 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053014566 hdd_connSetConnectionState(pHddStaCtx,
14567 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014568 /* Issue disconnect to CSR */
14569 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014570 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014571 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014572 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14573 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
14574 hddLog(LOG1,
14575 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
14576 } else if ( 0 != status ) {
14577 hddLog(LOGE,
14578 FL("csrRoamDisconnect failure, returned %d"),
14579 (int)status );
14580 result = -EINVAL;
14581 goto disconnected;
14582 }
14583 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014584 &pAdapter->disconnect_comp_var,
14585 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014586 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
14587 hddLog(LOGE,
14588 "%s: Failed to disconnect, timed out", __func__);
14589 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014590 }
14591 }
14592 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14593 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014594 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014595 &pAdapter->disconnect_comp_var,
14596 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014597 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014598 {
14599 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014600 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014601 }
14602 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014603disconnected:
14604 hddLog(LOG1,
14605 FL("Set HDD connState to eConnectionState_NotConnected"));
14606 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14607 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014608}
14609
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014610/**
14611 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
14612 * @adapter: Pointer to the HDD adapter
14613 * @req: Pointer to the structure cfg_connect_params receieved from user space
14614 *
14615 * This function will start reassociation if bssid hint, channel hint and
14616 * previous bssid parameters are present in the connect request
14617 *
14618 * Return: success if reassociation is happening
14619 * Error code if reassociation is not permitted or not happening
14620 */
14621#ifdef CFG80211_CONNECT_PREV_BSSID
14622static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14623 struct cfg80211_connect_params *req)
14624{
14625 int status = -EPERM;
14626 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
14627 hddLog(VOS_TRACE_LEVEL_INFO,
14628 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
14629 req->channel_hint->hw_value,
14630 MAC_ADDR_ARRAY(req->bssid_hint));
14631 status = hdd_reassoc(adapter, req->bssid_hint,
14632 req->channel_hint->hw_value,
14633 CONNECT_CMD_USERSPACE);
14634 }
14635 return status;
14636}
14637#else
14638static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
14639 struct cfg80211_connect_params *req)
14640{
14641 return -EPERM;
14642}
14643#endif
14644
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014645/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014646 * FUNCTION: __wlan_hdd_cfg80211_connect
14647 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014648 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014649static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014650 struct net_device *ndev,
14651 struct cfg80211_connect_params *req
14652 )
14653{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014654 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014655 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053014656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
14657 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014658 const u8 *bssid_hint = req->bssid_hint;
14659#else
14660 const u8 *bssid_hint = NULL;
14661#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014662 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014663 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014664 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014665
14666 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014667
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014668 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14669 TRACE_CODE_HDD_CFG80211_CONNECT,
14670 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014671 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014672 "%s: device_mode = %s (%d)", __func__,
14673 hdd_device_modetoString(pAdapter->device_mode),
14674 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014675
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014676 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014677 if (!pHddCtx)
14678 {
14679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14680 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014681 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014682 }
14683
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014684 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014685 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014686 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014687 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014688 }
14689
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053014690 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
14691 if (0 == status)
14692 return status;
14693
Agarwal Ashish51325b52014-06-16 16:50:49 +053014694
Jeff Johnson295189b2012-06-20 16:38:30 -070014695#ifdef WLAN_BTAMP_FEATURE
14696 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014697 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014698 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014699 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014700 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014701 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014702 }
14703#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014704
14705 //If Device Mode is Station Concurrent Sessions Exit BMps
14706 //P2P Mode will be taken care in Open/close adapter
14707 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014708 (vos_concurrent_open_sessions_running())) {
14709 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14710 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014711 }
14712
14713 /*Try disconnecting if already in connected state*/
14714 status = wlan_hdd_try_disconnect(pAdapter);
14715 if ( 0 > status)
14716 {
14717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14718 " connection"));
14719 return -EALREADY;
14720 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053014721 /* Check for max concurrent connections after doing disconnect if any*/
14722 if (vos_max_concurrent_connections_reached()) {
14723 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14724 return -ECONNREFUSED;
14725 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014726
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014728 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014729
14730 if ( 0 > status)
14731 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 __func__);
14734 return status;
14735 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053014736
14737 if (pHddCtx->spoofMacAddr.isEnabled)
14738 {
14739 hddLog(VOS_TRACE_LEVEL_INFO,
14740 "%s: MAC Spoofing enabled ", __func__);
14741 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14742 * to fill TxBds for probe request during SSID scan which may happen
14743 * as part of connect command
14744 */
14745 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
14746 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
14747 if (status != VOS_STATUS_SUCCESS)
14748 return -ECONNREFUSED;
14749 }
14750
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014751 if (req->channel)
14752 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070014753 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053014754 channel = 0;
14755 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14756 req->ssid_len, req->bssid,
14757 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014758
Sushant Kaushikd7083982015-03-18 14:33:24 +053014759 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014760 {
14761 //ReEnable BMPS if disabled
14762 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14763 (NULL != pHddCtx))
14764 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014765 if (pHddCtx->hdd_wlan_suspended)
14766 {
14767 hdd_set_pwrparams(pHddCtx);
14768 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014769 //ReEnable Bmps and Imps back
14770 hdd_enable_bmps_imps(pHddCtx);
14771 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014773 return status;
14774 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014775 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014776 EXIT();
14777 return status;
14778}
14779
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014780static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14781 struct net_device *ndev,
14782 struct cfg80211_connect_params *req)
14783{
14784 int ret;
14785 vos_ssr_protect(__func__);
14786 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14787 vos_ssr_unprotect(__func__);
14788
14789 return ret;
14790}
Jeff Johnson295189b2012-06-20 16:38:30 -070014791
14792/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014793 * FUNCTION: wlan_hdd_disconnect
14794 * This function is used to issue a disconnect request to SME
14795 */
14796int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14797{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014798 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014799 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014800 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014801 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014802
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014803 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014804
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014805 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014806 if (0 != status)
14807 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014808 return status;
14809 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053014810 /* Indicate sme of disconnect so that in progress connection or preauth
14811 * can be aborted
14812 */
14813 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014814 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014815 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014816
Agarwal Ashish47d18112014-08-04 19:55:07 +053014817 /* Need to apply spin lock before decreasing active sessions
14818 * as there can be chance for double decrement if context switch
14819 * Calls hdd_DisConnectHandler.
14820 */
14821
14822 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014823 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14824 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014825 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14826 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014827 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14828 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014829
Abhishek Singhf4669da2014-05-26 15:07:49 +053014830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014831 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14832
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014833 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014834
Mihir Shete182a0b22014-08-18 16:08:48 +053014835 /*
14836 * stop tx queues before deleting STA/BSS context from the firmware.
14837 * tx has to be disabled because the firmware can get busy dropping
14838 * the tx frames after BSS/STA has been deleted and will not send
14839 * back a response resulting in WDI timeout
14840 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014841 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014842 netif_tx_disable(pAdapter->dev);
14843 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014844
Mihir Shete182a0b22014-08-18 16:08:48 +053014845 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014846 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14847 pAdapter->sessionId, reason);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014848 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14849 {
14850 hddLog(LOG1,
14851 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014852 }
14853 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014854 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014855 hddLog(LOGE,
14856 FL("csrRoamDisconnect failure, returned %d"),
14857 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014858 result = -EINVAL;
14859 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014860 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014861 ret = wait_for_completion_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014862 &pAdapter->disconnect_comp_var,
14863 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014864 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014865 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014866 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014867 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014868 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014869 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014870disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053014871 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014872 FL("Set HDD connState to eConnectionState_NotConnected"));
14873 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014874#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
14875 /* Sending disconnect event to userspace for kernel version < 3.11
14876 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14877 */
14878 hddLog(LOG1, FL("Send disconnected event to userspace"));
14879
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053014880 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053014881 WLAN_REASON_UNSPECIFIED);
14882#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014883
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014884 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014885 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014886}
14887
14888
14889/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014890 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014891 * This function is used to issue a disconnect request to SME
14892 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014893static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014894 struct net_device *dev,
14895 u16 reason
14896 )
14897{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014899 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014900 tCsrRoamProfile *pRoamProfile;
14901 hdd_station_ctx_t *pHddStaCtx;
14902 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014903#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014904 tANI_U8 staIdx;
14905#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014906
Jeff Johnson295189b2012-06-20 16:38:30 -070014907 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014908
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014909 if (!pAdapter) {
14910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14911 return -EINVAL;
14912 }
14913
14914 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14915 if (!pHddStaCtx) {
14916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14917 return -EINVAL;
14918 }
14919
14920 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14921 status = wlan_hdd_validate_context(pHddCtx);
14922 if (0 != status)
14923 {
14924 return status;
14925 }
14926
14927 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14928
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014929 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14930 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14931 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14933 __func__, hdd_device_modetoString(pAdapter->device_mode),
14934 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014935
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014936 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14937 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014938
Jeff Johnson295189b2012-06-20 16:38:30 -070014939 if (NULL != pRoamProfile)
14940 {
14941 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014942 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14943 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014945 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014947 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014948 switch(reason)
14949 {
14950 case WLAN_REASON_MIC_FAILURE:
14951 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14952 break;
14953
14954 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14955 case WLAN_REASON_DISASSOC_AP_BUSY:
14956 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14957 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14958 break;
14959
14960 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14961 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014962 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014963 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14964 break;
14965
Jeff Johnson295189b2012-06-20 16:38:30 -070014966 default:
14967 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14968 break;
14969 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014970 pScanInfo = &pHddCtx->scan_info;
14971 if (pScanInfo->mScanPending)
14972 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014973 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014974 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014975 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014976 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014977 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014978 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014979#ifdef FEATURE_WLAN_TDLS
14980 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014981 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014982 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014983 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14984 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014985 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014986 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014987 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014989 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014990 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014991 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014992 status = sme_DeleteTdlsPeerSta(
14993 WLAN_HDD_GET_HAL_CTX(pAdapter),
14994 pAdapter->sessionId,
14995 mac);
14996 if (status != eHAL_STATUS_SUCCESS) {
14997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14998 return -EPERM;
14999 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080015000 }
15001 }
15002#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015003 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015004 status = wlan_hdd_disconnect(pAdapter, reasonCode);
15005 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 {
15007 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015008 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015009 __func__, (int)status );
15010 return -EINVAL;
15011 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015012 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053015013 else
15014 {
15015 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
15016 "called while in %d state", __func__,
15017 pHddStaCtx->conn_info.connState);
15018 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015019 }
15020 else
15021 {
15022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
15023 }
15024
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015025 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015026 return status;
15027}
15028
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015029static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
15030 struct net_device *dev,
15031 u16 reason
15032 )
15033{
15034 int ret;
15035 vos_ssr_protect(__func__);
15036 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
15037 vos_ssr_unprotect(__func__);
15038
15039 return ret;
15040}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053015041
Jeff Johnson295189b2012-06-20 16:38:30 -070015042/*
15043 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015044 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015045 * settings in IBSS mode.
15046 */
15047static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015048 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015049 struct cfg80211_ibss_params *params
15050 )
15051{
15052 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015053 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015054 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15055 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015056
Jeff Johnson295189b2012-06-20 16:38:30 -070015057 ENTER();
15058
15059 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070015060 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070015061
15062 if (params->ie_len && ( NULL != params->ie) )
15063 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015064 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15065 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015066 {
15067 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15068 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15069 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015070 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070015071 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015072 tDot11fIEWPA dot11WPAIE;
15073 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015074 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015075
Wilson Yang00256342013-10-10 23:13:38 -070015076 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015077 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
15078 params->ie_len, DOT11F_EID_WPA);
15079 if ( NULL != ie )
15080 {
15081 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15082 // Unpack the WPA IE
15083 //Skip past the EID byte and length byte - and four byte WiFi OUI
15084 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
15085 &ie[2+4],
15086 ie[1] - 4,
15087 &dot11WPAIE);
15088 /*Extract the multicast cipher, the encType for unicast
15089 cipher for wpa-none is none*/
15090 encryptionType =
15091 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
15092 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015093 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070015094
Jeff Johnson295189b2012-06-20 16:38:30 -070015095 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
15096
15097 if (0 > status)
15098 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015100 __func__);
15101 return status;
15102 }
15103 }
15104
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015105 pWextState->roamProfile.AuthType.authType[0] =
15106 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070015107 eCSR_AUTH_TYPE_OPEN_SYSTEM;
15108
15109 if (params->privacy)
15110 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015111 /* Security enabled IBSS, At this time there is no information available
15112 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070015113 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015114 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070015115 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015116 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070015117 *enable privacy bit in beacons */
15118
15119 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
15120 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070015121 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
15122 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070015123 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15124 pWextState->roamProfile.EncryptionType.numEntries = 1;
15125 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070015126 return status;
15127}
15128
15129/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015130 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015131 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015132 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015133static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015134 struct net_device *dev,
15135 struct cfg80211_ibss_params *params
15136 )
15137{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015138 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070015139 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15140 tCsrRoamProfile *pRoamProfile;
15141 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015142 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15143 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015144 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070015145
15146 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015147
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15149 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
15150 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015151 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015152 "%s: device_mode = %s (%d)", __func__,
15153 hdd_device_modetoString(pAdapter->device_mode),
15154 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015155
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015156 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015157 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015158 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015159 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015160 }
15161
15162 if (NULL == pWextState)
15163 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015164 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015165 __func__);
15166 return -EIO;
15167 }
15168
Agarwal Ashish51325b52014-06-16 16:50:49 +053015169 if (vos_max_concurrent_connections_reached()) {
15170 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15171 return -ECONNREFUSED;
15172 }
15173
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053015174 /*Try disconnecting if already in connected state*/
15175 status = wlan_hdd_try_disconnect(pAdapter);
15176 if ( 0 > status)
15177 {
15178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
15179 " IBSS connection"));
15180 return -EALREADY;
15181 }
15182
Jeff Johnson295189b2012-06-20 16:38:30 -070015183 pRoamProfile = &pWextState->roamProfile;
15184
15185 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
15186 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015187 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015188 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015189 return -EINVAL;
15190 }
15191
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015192 /* BSSID is provided by upper layers hence no need to AUTO generate */
15193 if (NULL != params->bssid) {
15194 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15195 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
15196 hddLog (VOS_TRACE_LEVEL_ERROR,
15197 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15198 return -EIO;
15199 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015200 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015201 }
krunal sonie9002db2013-11-25 14:24:17 -080015202 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
15203 {
15204 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
15205 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
15206 {
15207 hddLog (VOS_TRACE_LEVEL_ERROR,
15208 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
15209 return -EIO;
15210 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015211
15212 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080015213 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015214 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080015215 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070015216
Jeff Johnson295189b2012-06-20 16:38:30 -070015217 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070015218 if (NULL !=
15219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15220 params->chandef.chan)
15221#else
15222 params->channel)
15223#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015224 {
15225 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015226 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15227 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
15228 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15229 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015230
15231 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015232 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070015233 ieee80211_frequency_to_channel(
15234#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
15235 params->chandef.chan->center_freq);
15236#else
15237 params->channel->center_freq);
15238#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015239
15240 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15241 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070015242 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015243 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
15244 __func__);
15245 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070015246 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015247
15248 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015249 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015250 if (channelNum == validChan[indx])
15251 {
15252 break;
15253 }
15254 }
15255 if (indx >= numChans)
15256 {
15257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 __func__, channelNum);
15259 return -EINVAL;
15260 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015261 /* Set the Operational Channel */
15262 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
15263 channelNum);
15264 pRoamProfile->ChannelInfo.numOfChannels = 1;
15265 pHddStaCtx->conn_info.operationChannel = channelNum;
15266 pRoamProfile->ChannelInfo.ChannelList =
15267 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070015268 }
15269
15270 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015271 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070015272 if (status < 0)
15273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 __func__);
15276 return status;
15277 }
15278
15279 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015280 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053015281 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015282 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015283
15284 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070015285 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015286
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015287 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015288 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015289}
15290
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015291static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
15292 struct net_device *dev,
15293 struct cfg80211_ibss_params *params
15294 )
15295{
15296 int ret = 0;
15297
15298 vos_ssr_protect(__func__);
15299 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
15300 vos_ssr_unprotect(__func__);
15301
15302 return ret;
15303}
15304
Jeff Johnson295189b2012-06-20 16:38:30 -070015305/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015306 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015307 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070015308 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015309static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015310 struct net_device *dev
15311 )
15312{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015313 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015314 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15315 tCsrRoamProfile *pRoamProfile;
15316 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015317 int status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015318#ifdef WLAN_FEATURE_RMC
15319 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
15320#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015321
15322 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015323
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015324 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15325 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15326 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015327 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015328 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015329 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015330 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015331 }
15332
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015333 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15334 hdd_device_modetoString(pAdapter->device_mode),
15335 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015336 if (NULL == pWextState)
15337 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015338 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 __func__);
15340 return -EIO;
15341 }
15342
15343 pRoamProfile = &pWextState->roamProfile;
15344
15345 /* Issue disconnect only if interface type is set to IBSS */
15346 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15347 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015348 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015349 __func__);
15350 return -EINVAL;
15351 }
15352
Abhishek Singh7cd040e2016-01-07 10:51:04 +053015353#ifdef WLAN_FEATURE_RMC
15354 /* Clearing add IE of beacon */
15355 if (ccmCfgSetStr(pHddCtx->hHal,
15356 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
15357 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
15358 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15359 {
15360 hddLog (VOS_TRACE_LEVEL_ERROR,
15361 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
15362 return -EINVAL;
15363 }
15364 if (ccmCfgSetInt(pHddCtx->hHal,
15365 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
15366 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
15367 {
15368 hddLog (VOS_TRACE_LEVEL_ERROR,
15369 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
15370 __func__);
15371 return -EINVAL;
15372 }
15373
15374 // Reset WNI_CFG_PROBE_RSP Flags
15375 wlan_hdd_reset_prob_rspies(pAdapter);
15376
15377 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15378 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
15379 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15380 {
15381 hddLog (VOS_TRACE_LEVEL_ERROR,
15382 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
15383 __func__);
15384 return -EINVAL;
15385 }
15386#endif
15387
Jeff Johnson295189b2012-06-20 16:38:30 -070015388 /* Issue Disconnect request */
15389 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15390 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15391 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015393 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 return 0;
15395}
15396
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015397static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15398 struct net_device *dev
15399 )
15400{
15401 int ret = 0;
15402
15403 vos_ssr_protect(__func__);
15404 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15405 vos_ssr_unprotect(__func__);
15406
15407 return ret;
15408}
15409
Jeff Johnson295189b2012-06-20 16:38:30 -070015410/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015411 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 * This function is used to set the phy parameters
15413 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15414 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015415static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015416 u32 changed)
15417{
15418 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15419 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015420 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015421
15422 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015423
15424 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015425 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15426 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015427
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015428 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015429 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015430 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015431 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015432 }
15433
Jeff Johnson295189b2012-06-20 16:38:30 -070015434 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15435 {
15436 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15437 WNI_CFG_RTS_THRESHOLD_STAMAX :
15438 wiphy->rts_threshold;
15439
15440 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015441 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015443 hddLog(VOS_TRACE_LEVEL_ERROR,
15444 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015445 __func__, rts_threshold);
15446 return -EINVAL;
15447 }
15448
15449 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15450 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015451 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015453 hddLog(VOS_TRACE_LEVEL_ERROR,
15454 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015455 __func__, rts_threshold);
15456 return -EIO;
15457 }
15458
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015459 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015460 rts_threshold);
15461 }
15462
15463 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15464 {
15465 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15466 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15467 wiphy->frag_threshold;
15468
15469 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015470 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015471 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015472 hddLog(VOS_TRACE_LEVEL_ERROR,
15473 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015474 frag_threshold);
15475 return -EINVAL;
15476 }
15477
15478 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15479 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015480 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015482 hddLog(VOS_TRACE_LEVEL_ERROR,
15483 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015484 __func__, frag_threshold);
15485 return -EIO;
15486 }
15487
15488 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15489 frag_threshold);
15490 }
15491
15492 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15493 || (changed & WIPHY_PARAM_RETRY_LONG))
15494 {
15495 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15496 wiphy->retry_short :
15497 wiphy->retry_long;
15498
15499 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15500 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15501 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015503 __func__, retry_value);
15504 return -EINVAL;
15505 }
15506
15507 if (changed & WIPHY_PARAM_RETRY_SHORT)
15508 {
15509 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15510 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015511 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015512 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015513 hddLog(VOS_TRACE_LEVEL_ERROR,
15514 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015515 __func__, retry_value);
15516 return -EIO;
15517 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015518 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015519 __func__, retry_value);
15520 }
15521 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15522 {
15523 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15524 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015525 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015526 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015527 hddLog(VOS_TRACE_LEVEL_ERROR,
15528 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015529 __func__, retry_value);
15530 return -EIO;
15531 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015532 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015533 __func__, retry_value);
15534 }
15535 }
15536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015537 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015538 return 0;
15539}
15540
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015541static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15542 u32 changed)
15543{
15544 int ret;
15545
15546 vos_ssr_protect(__func__);
15547 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15548 vos_ssr_unprotect(__func__);
15549
15550 return ret;
15551}
15552
Jeff Johnson295189b2012-06-20 16:38:30 -070015553/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015554 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015555 * This function is used to set the txpower
15556 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015557static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015558#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15559 struct wireless_dev *wdev,
15560#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015561#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015562 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015563#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015564 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015565#endif
15566 int dbm)
15567{
15568 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015569 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15571 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015572 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015573
15574 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015575
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015576 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15577 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15578 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015579 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015580 if (0 != status)
15581 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015582 return status;
15583 }
15584
15585 hHal = pHddCtx->hHal;
15586
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015587 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15588 dbm, ccmCfgSetCallback,
15589 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015590 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015591 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015592 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15593 return -EIO;
15594 }
15595
15596 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15597 dbm);
15598
15599 switch(type)
15600 {
15601 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15602 /* Fall through */
15603 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15604 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15607 __func__);
15608 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015609 }
15610 break;
15611 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015613 __func__);
15614 return -EOPNOTSUPP;
15615 break;
15616 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015617 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15618 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015619 return -EIO;
15620 }
15621
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015622 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015623 return 0;
15624}
15625
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015626static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15627#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15628 struct wireless_dev *wdev,
15629#endif
15630#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15631 enum tx_power_setting type,
15632#else
15633 enum nl80211_tx_power_setting type,
15634#endif
15635 int dbm)
15636{
15637 int ret;
15638 vos_ssr_protect(__func__);
15639 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15640#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15641 wdev,
15642#endif
15643#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15644 type,
15645#else
15646 type,
15647#endif
15648 dbm);
15649 vos_ssr_unprotect(__func__);
15650
15651 return ret;
15652}
15653
Jeff Johnson295189b2012-06-20 16:38:30 -070015654/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015655 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015656 * This function is used to read the txpower
15657 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015658static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015659#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15660 struct wireless_dev *wdev,
15661#endif
15662 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015663{
15664
15665 hdd_adapter_t *pAdapter;
15666 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015667 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015668
Jeff Johnsone7245742012-09-05 17:12:55 -070015669 ENTER();
15670
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015671 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015672 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015673 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015674 *dbm = 0;
15675 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015676 }
15677
Jeff Johnson295189b2012-06-20 16:38:30 -070015678 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15679 if (NULL == pAdapter)
15680 {
15681 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15682 return -ENOENT;
15683 }
15684
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015685 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15686 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15687 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015688 wlan_hdd_get_classAstats(pAdapter);
15689 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15690
Jeff Johnsone7245742012-09-05 17:12:55 -070015691 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 return 0;
15693}
15694
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015695static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15696#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15697 struct wireless_dev *wdev,
15698#endif
15699 int *dbm)
15700{
15701 int ret;
15702
15703 vos_ssr_protect(__func__);
15704 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15705#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15706 wdev,
15707#endif
15708 dbm);
15709 vos_ssr_unprotect(__func__);
15710
15711 return ret;
15712}
15713
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015714static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15716 const u8* mac,
15717#else
15718 u8* mac,
15719#endif
15720 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015721{
15722 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15723 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15724 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015725 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015726
15727 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15728 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015729
15730 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15731 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15732 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15733 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15734 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15735 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15736 tANI_U16 maxRate = 0;
15737 tANI_U16 myRate;
15738 tANI_U16 currentRate = 0;
15739 tANI_U8 maxSpeedMCS = 0;
15740 tANI_U8 maxMCSIdx = 0;
15741 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015742 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015743 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015744 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015745
Leo Chang6f8870f2013-03-26 18:11:36 -070015746#ifdef WLAN_FEATURE_11AC
15747 tANI_U32 vht_mcs_map;
15748 eDataRate11ACMaxMcs vhtMaxMcs;
15749#endif /* WLAN_FEATURE_11AC */
15750
Jeff Johnsone7245742012-09-05 17:12:55 -070015751 ENTER();
15752
Jeff Johnson295189b2012-06-20 16:38:30 -070015753 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15754 (0 == ssidlen))
15755 {
15756 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15757 " Invalid ssidlen, %d", __func__, ssidlen);
15758 /*To keep GUI happy*/
15759 return 0;
15760 }
15761
Mukul Sharma811205f2014-07-09 21:07:30 +053015762 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15763 {
15764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15765 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053015766 /* return a cached value */
15767 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053015768 return 0;
15769 }
15770
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015771 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015772 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015773 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015774 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015775 }
15776
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015777 wlan_hdd_get_station_stats(pAdapter);
15778 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015779
Kiet Lam3b17fc82013-09-27 05:24:08 +053015780 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15781 sinfo->filled |= STATION_INFO_SIGNAL;
15782
c_hpothu09f19542014-05-30 21:53:31 +053015783 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015784 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15785 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015786 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015787 {
15788 rate_flags = pAdapter->maxRateFlags;
15789 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015790
Jeff Johnson295189b2012-06-20 16:38:30 -070015791 //convert to the UI units of 100kbps
15792 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15793
15794#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015795 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 -070015796 sinfo->signal,
15797 pCfg->reportMaxLinkSpeed,
15798 myRate,
15799 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015800 (int) pCfg->linkSpeedRssiMid,
15801 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015802 (int) rate_flags,
15803 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015804#endif //LINKSPEED_DEBUG_ENABLED
15805
15806 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15807 {
15808 // we do not want to necessarily report the current speed
15809 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15810 {
15811 // report the max possible speed
15812 rssidx = 0;
15813 }
15814 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15815 {
15816 // report the max possible speed with RSSI scaling
15817 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15818 {
15819 // report the max possible speed
15820 rssidx = 0;
15821 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015822 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015823 {
15824 // report middle speed
15825 rssidx = 1;
15826 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015827 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15828 {
15829 // report middle speed
15830 rssidx = 2;
15831 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015832 else
15833 {
15834 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015835 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015836 }
15837 }
15838 else
15839 {
15840 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15841 hddLog(VOS_TRACE_LEVEL_ERROR,
15842 "%s: Invalid value for reportMaxLinkSpeed: %u",
15843 __func__, pCfg->reportMaxLinkSpeed);
15844 rssidx = 0;
15845 }
15846
15847 maxRate = 0;
15848
15849 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015850 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15851 OperationalRates, &ORLeng))
15852 {
15853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15854 /*To keep GUI happy*/
15855 return 0;
15856 }
15857
Jeff Johnson295189b2012-06-20 16:38:30 -070015858 for (i = 0; i < ORLeng; i++)
15859 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015860 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015861 {
15862 /* Validate Rate Set */
15863 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15864 {
15865 currentRate = supported_data_rate[j].supported_rate[rssidx];
15866 break;
15867 }
15868 }
15869 /* Update MAX rate */
15870 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15871 }
15872
15873 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015874 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15875 ExtendedRates, &ERLeng))
15876 {
15877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15878 /*To keep GUI happy*/
15879 return 0;
15880 }
15881
Jeff Johnson295189b2012-06-20 16:38:30 -070015882 for (i = 0; i < ERLeng; i++)
15883 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015884 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015885 {
15886 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15887 {
15888 currentRate = supported_data_rate[j].supported_rate[rssidx];
15889 break;
15890 }
15891 }
15892 /* Update MAX rate */
15893 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15894 }
c_hpothu79aab322014-07-14 21:11:01 +053015895
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015896 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015897 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015898 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015899 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015900 {
c_hpothu79aab322014-07-14 21:11:01 +053015901 if (rate_flags & eHAL_TX_RATE_VHT80)
15902 mode = 2;
15903 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15904 mode = 1;
15905 else
15906 mode = 0;
15907
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015908 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15909 MCSRates, &MCSLeng))
15910 {
15911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15912 /*To keep GUI happy*/
15913 return 0;
15914 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015915 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015916#ifdef WLAN_FEATURE_11AC
15917 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015918 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015919 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015920 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015921 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015922 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015923 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015924 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015925 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015926 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015927 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015928 maxMCSIdx = 7;
15929 }
15930 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15931 {
15932 maxMCSIdx = 8;
15933 }
15934 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15935 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015936 //VHT20 is supporting 0~8
15937 if (rate_flags & eHAL_TX_RATE_VHT20)
15938 maxMCSIdx = 8;
15939 else
15940 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015941 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015942
c_hpothu79aab322014-07-14 21:11:01 +053015943 if (0 != rssidx)/*check for scaled */
15944 {
15945 //get middle rate MCS index if rssi=1/2
15946 for (i=0; i <= maxMCSIdx; i++)
15947 {
15948 if (sinfo->signal <= rssiMcsTbl[mode][i])
15949 {
15950 maxMCSIdx = i;
15951 break;
15952 }
15953 }
15954 }
15955
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015956 if (rate_flags & eHAL_TX_RATE_VHT80)
15957 {
15958 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15959 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15960 }
15961 else if (rate_flags & eHAL_TX_RATE_VHT40)
15962 {
15963 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15964 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15965 }
15966 else if (rate_flags & eHAL_TX_RATE_VHT20)
15967 {
15968 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15969 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15970 }
15971
Leo Chang6f8870f2013-03-26 18:11:36 -070015972 maxSpeedMCS = 1;
15973 if (currentRate > maxRate)
15974 {
15975 maxRate = currentRate;
15976 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015977
Leo Chang6f8870f2013-03-26 18:11:36 -070015978 }
15979 else
15980#endif /* WLAN_FEATURE_11AC */
15981 {
15982 if (rate_flags & eHAL_TX_RATE_HT40)
15983 {
15984 rateFlag |= 1;
15985 }
15986 if (rate_flags & eHAL_TX_RATE_SGI)
15987 {
15988 rateFlag |= 2;
15989 }
15990
Girish Gowli01abcee2014-07-31 20:18:55 +053015991 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015992 if (rssidx == 1 || rssidx == 2)
15993 {
15994 //get middle rate MCS index if rssi=1/2
15995 for (i=0; i <= 7; i++)
15996 {
15997 if (sinfo->signal <= rssiMcsTbl[mode][i])
15998 {
15999 temp = i+1;
16000 break;
16001 }
16002 }
16003 }
c_hpothu79aab322014-07-14 21:11:01 +053016004
16005 for (i = 0; i < MCSLeng; i++)
16006 {
Leo Chang6f8870f2013-03-26 18:11:36 -070016007 for (j = 0; j < temp; j++)
16008 {
16009 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
16010 {
16011 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016012 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016013 break;
16014 }
16015 }
16016 if ((j < temp) && (currentRate > maxRate))
16017 {
16018 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070016019 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016020 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053016021 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070016022 }
16023 }
16024
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016025 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
16026 {
16027 maxRate = myRate;
16028 maxSpeedMCS = 1;
16029 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16030 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016031 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053016032 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070016033 {
16034 maxRate = myRate;
16035 if (rate_flags & eHAL_TX_RATE_LEGACY)
16036 {
16037 maxSpeedMCS = 0;
16038 }
16039 else
16040 {
16041 maxSpeedMCS = 1;
16042 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
16043 }
16044 }
16045
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016046 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070016047 {
16048 sinfo->txrate.legacy = maxRate;
16049#ifdef LINKSPEED_DEBUG_ENABLED
16050 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
16051#endif //LINKSPEED_DEBUG_ENABLED
16052 }
16053 else
16054 {
16055 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070016056#ifdef WLAN_FEATURE_11AC
16057 sinfo->txrate.nss = 1;
16058 if (rate_flags & eHAL_TX_RATE_VHT80)
16059 {
16060 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016061 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070016062 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016063 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070016064 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016065 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16066 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16067 }
16068 else if (rate_flags & eHAL_TX_RATE_VHT20)
16069 {
16070 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16071 }
16072#endif /* WLAN_FEATURE_11AC */
16073 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
16074 {
16075 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16076 if (rate_flags & eHAL_TX_RATE_HT40)
16077 {
16078 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16079 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016080 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016081 if (rate_flags & eHAL_TX_RATE_SGI)
16082 {
16083 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16084 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053016085
Jeff Johnson295189b2012-06-20 16:38:30 -070016086#ifdef LINKSPEED_DEBUG_ENABLED
16087 pr_info("Reporting MCS rate %d flags %x\n",
16088 sinfo->txrate.mcs,
16089 sinfo->txrate.flags );
16090#endif //LINKSPEED_DEBUG_ENABLED
16091 }
16092 }
16093 else
16094 {
16095 // report current rate instead of max rate
16096
16097 if (rate_flags & eHAL_TX_RATE_LEGACY)
16098 {
16099 //provide to the UI in units of 100kbps
16100 sinfo->txrate.legacy = myRate;
16101#ifdef LINKSPEED_DEBUG_ENABLED
16102 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
16103#endif //LINKSPEED_DEBUG_ENABLED
16104 }
16105 else
16106 {
16107 //must be MCS
16108 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070016109#ifdef WLAN_FEATURE_11AC
16110 sinfo->txrate.nss = 1;
16111 if (rate_flags & eHAL_TX_RATE_VHT80)
16112 {
16113 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
16114 }
16115 else
16116#endif /* WLAN_FEATURE_11AC */
16117 {
16118 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
16119 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016120 if (rate_flags & eHAL_TX_RATE_SGI)
16121 {
16122 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
16123 }
16124 if (rate_flags & eHAL_TX_RATE_HT40)
16125 {
16126 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
16127 }
Leo Chang6f8870f2013-03-26 18:11:36 -070016128#ifdef WLAN_FEATURE_11AC
16129 else if (rate_flags & eHAL_TX_RATE_VHT80)
16130 {
16131 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
16132 }
16133#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070016134#ifdef LINKSPEED_DEBUG_ENABLED
16135 pr_info("Reporting actual MCS rate %d flags %x\n",
16136 sinfo->txrate.mcs,
16137 sinfo->txrate.flags );
16138#endif //LINKSPEED_DEBUG_ENABLED
16139 }
16140 }
16141 sinfo->filled |= STATION_INFO_TX_BITRATE;
16142
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016143 sinfo->tx_packets =
16144 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
16145 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
16146 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
16147 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
16148
16149 sinfo->tx_retries =
16150 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
16151 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
16152 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
16153 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
16154
16155 sinfo->tx_failed =
16156 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
16157 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
16158 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
16159 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
16160
16161 sinfo->filled |=
16162 STATION_INFO_TX_PACKETS |
16163 STATION_INFO_TX_RETRIES |
16164 STATION_INFO_TX_FAILED;
16165
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053016166 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
16167 sinfo->filled |= STATION_INFO_RX_PACKETS;
16168
16169 if (rate_flags & eHAL_TX_RATE_LEGACY)
16170 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
16171 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
16172 sinfo->rx_packets);
16173 else
16174 hddLog(LOG1,
16175 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
16176 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
16177 sinfo->tx_packets, sinfo->rx_packets);
16178
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016179 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16180 TRACE_CODE_HDD_CFG80211_GET_STA,
16181 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070016182 EXIT();
16183 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070016184}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16186static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16187 const u8* mac, struct station_info *sinfo)
16188#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016189static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
16190 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016191#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016192{
16193 int ret;
16194
16195 vos_ssr_protect(__func__);
16196 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
16197 vos_ssr_unprotect(__func__);
16198
16199 return ret;
16200}
16201
16202static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070016203 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070016204{
16205 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016206 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016207 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016208 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016209
Jeff Johnsone7245742012-09-05 17:12:55 -070016210 ENTER();
16211
Jeff Johnson295189b2012-06-20 16:38:30 -070016212 if (NULL == pAdapter)
16213 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016215 return -ENODEV;
16216 }
16217
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016218 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16219 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
16220 pAdapter->sessionId, timeout));
16221
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016222 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016223 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016224 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016225 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016226 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016227 }
16228
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016229 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
16230 (TRUE == pHddCtx->hdd_wlan_suspended) &&
16231 (pHddCtx->cfg_ini->fhostArpOffload) &&
16232 (eConnectionState_Associated ==
16233 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
16234 {
Amar Singhald53568e2013-09-26 11:03:45 -070016235
16236 hddLog(VOS_TRACE_LEVEL_INFO,
16237 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053016238 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016239 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16240 {
16241 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016242 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053016243 __func__, vos_status);
16244 }
16245 }
16246
Jeff Johnson295189b2012-06-20 16:38:30 -070016247 /**The get power cmd from the supplicant gets updated by the nl only
16248 *on successful execution of the function call
16249 *we are oppositely mapped w.r.t mode in the driver
16250 **/
16251 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
16252
16253 if (VOS_STATUS_E_FAILURE == vos_status)
16254 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16256 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 return -EINVAL;
16258 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016259 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016260 return 0;
16261}
16262
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016263static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
16264 struct net_device *dev, bool mode, int timeout)
16265{
16266 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016267
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016268 vos_ssr_protect(__func__);
16269 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
16270 vos_ssr_unprotect(__func__);
16271
16272 return ret;
16273}
Sushant Kaushik084f6592015-09-10 13:11:56 +053016274
Jeff Johnson295189b2012-06-20 16:38:30 -070016275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016276static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
16277 struct net_device *netdev,
16278 u8 key_index)
16279{
16280 ENTER();
16281 return 0;
16282}
16283
Jeff Johnson295189b2012-06-20 16:38:30 -070016284static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016285 struct net_device *netdev,
16286 u8 key_index)
16287{
16288 int ret;
16289 vos_ssr_protect(__func__);
16290 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
16291 vos_ssr_unprotect(__func__);
16292 return ret;
16293}
16294#endif //LINUX_VERSION_CODE
16295
16296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16297static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16298 struct net_device *dev,
16299 struct ieee80211_txq_params *params)
16300{
16301 ENTER();
16302 return 0;
16303}
16304#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16305static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
16306 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016307{
Jeff Johnsone7245742012-09-05 17:12:55 -070016308 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070016309 return 0;
16310}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016311#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070016312
16313#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
16314static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016315 struct net_device *dev,
16316 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070016317{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016318 int ret;
16319
16320 vos_ssr_protect(__func__);
16321 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
16322 vos_ssr_unprotect(__func__);
16323 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016324}
16325#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16326static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
16327 struct ieee80211_txq_params *params)
16328{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016329 int ret;
16330
16331 vos_ssr_protect(__func__);
16332 ret = __wlan_hdd_set_txq_params(wiphy, params);
16333 vos_ssr_unprotect(__func__);
16334 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070016335}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016336#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016337
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016338static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016339 struct net_device *dev,
16340 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070016341{
16342 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016343 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016344 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016345 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016346 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016347 v_CONTEXT_t pVosContext = NULL;
16348 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016349
Jeff Johnsone7245742012-09-05 17:12:55 -070016350 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016351
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016352 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070016353 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016355 return -EINVAL;
16356 }
16357
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016358 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16359 TRACE_CODE_HDD_CFG80211_DEL_STA,
16360 pAdapter->sessionId, pAdapter->device_mode));
16361
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016362 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16363 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016364 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016365 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016366 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016367 }
16368
Jeff Johnson295189b2012-06-20 16:38:30 -070016369 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016370 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016371 )
16372 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016373 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16374 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16375 if(pSapCtx == NULL){
16376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16377 FL("psapCtx is NULL"));
16378 return -ENOENT;
16379 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016380 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016381 {
16382 v_U16_t i;
16383 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16384 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016385 if ((pSapCtx->aStaInfo[i].isUsed) &&
16386 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016387 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016388 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016389 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016390 ETHER_ADDR_LEN);
16391
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016393 "%s: Delete STA with MAC::"
16394 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016395 __func__,
16396 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16397 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016398 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016399 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016400 }
16401 }
16402 }
16403 else
16404 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016405
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016406 vos_status = hdd_softap_GetStaId(pAdapter,
16407 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016408 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16409 {
16410 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016411 "%s: Skip this DEL STA as this is not used::"
16412 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016413 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016414 return -ENOENT;
16415 }
16416
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016417 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016418 {
16419 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016420 "%s: Skip this DEL STA as deauth is in progress::"
16421 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016422 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016423 return -ENOENT;
16424 }
16425
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016426 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016427
Jeff Johnson295189b2012-06-20 16:38:30 -070016428 hddLog(VOS_TRACE_LEVEL_INFO,
16429 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016430 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016431 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016432 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016433
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016434 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016435 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16436 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016437 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016438 hddLog(VOS_TRACE_LEVEL_INFO,
16439 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016440 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016441 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016442 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016443 return -ENOENT;
16444 }
16445
Jeff Johnson295189b2012-06-20 16:38:30 -070016446 }
16447 }
16448
16449 EXIT();
16450
16451 return 0;
16452}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016453
16454#ifdef CFG80211_DEL_STA_V2
16455static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16456 struct net_device *dev,
16457 struct station_del_parameters *param)
16458#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16460static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16461 struct net_device *dev, const u8 *mac)
16462#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016463static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16464 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016465#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016466#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016467{
16468 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016469 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016470
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016471 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016472
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016473#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016474 if (NULL == param) {
16475 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016476 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016477 return -EINVAL;
16478 }
16479
16480 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16481 param->subtype, &delStaParams);
16482
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016483#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016484 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016485 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016486#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016487 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16488
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016489 vos_ssr_unprotect(__func__);
16490
16491 return ret;
16492}
16493
16494static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016495 struct net_device *dev,
16496#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16497 const u8 *mac,
16498#else
16499 u8 *mac,
16500#endif
16501 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016502{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016503 hdd_adapter_t *pAdapter;
16504 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016505 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016506#ifdef FEATURE_WLAN_TDLS
16507 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016508
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016509 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016510
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016511 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16512 if (NULL == pAdapter)
16513 {
16514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16515 "%s: Adapter is NULL",__func__);
16516 return -EINVAL;
16517 }
16518 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16519 status = wlan_hdd_validate_context(pHddCtx);
16520 if (0 != status)
16521 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016522 return status;
16523 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16526 TRACE_CODE_HDD_CFG80211_ADD_STA,
16527 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016528 mask = params->sta_flags_mask;
16529
16530 set = params->sta_flags_set;
16531
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016533 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16534 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016535
16536 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16537 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016538 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016539 }
16540 }
16541#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016542 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016543 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016544}
16545
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016546#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16547static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16548 struct net_device *dev, const u8 *mac,
16549 struct station_parameters *params)
16550#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016551static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16552 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016553#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016554{
16555 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016556
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016557 vos_ssr_protect(__func__);
16558 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16559 vos_ssr_unprotect(__func__);
16560
16561 return ret;
16562}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016563#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016564
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016565static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016566 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016567{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016568 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16569 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016570 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016571 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016572 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016573 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016574
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016575 ENTER();
16576
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016577 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016578 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016579 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016581 return -EINVAL;
16582 }
16583
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016584 if (!pmksa) {
16585 hddLog(LOGE, FL("pmksa is NULL"));
16586 return -EINVAL;
16587 }
16588
16589 if (!pmksa->bssid || !pmksa->pmkid) {
16590 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16591 pmksa->bssid, pmksa->pmkid);
16592 return -EINVAL;
16593 }
16594
16595 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16596 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16597
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016598 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16599 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016600 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016601 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016602 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016603 }
16604
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016605 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016606 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16607
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016608 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16609 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016610
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016611 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016612 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016613 &pmk_id, 1, FALSE);
16614
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016615 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16616 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16617 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016619 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016620 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016621}
16622
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016623static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16624 struct cfg80211_pmksa *pmksa)
16625{
16626 int ret;
16627
16628 vos_ssr_protect(__func__);
16629 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16630 vos_ssr_unprotect(__func__);
16631
16632 return ret;
16633}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016634
Wilson Yang6507c4e2013-10-01 20:11:19 -070016635
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016636static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016637 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016638{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16640 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016641 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016642 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016643
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016644 ENTER();
16645
Wilson Yang6507c4e2013-10-01 20:11:19 -070016646 /* Validate pAdapter */
16647 if (NULL == pAdapter)
16648 {
16649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16650 return -EINVAL;
16651 }
16652
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016653 if (!pmksa) {
16654 hddLog(LOGE, FL("pmksa is NULL"));
16655 return -EINVAL;
16656 }
16657
16658 if (!pmksa->bssid) {
16659 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16660 return -EINVAL;
16661 }
16662
Kiet Lam98c46a12014-10-31 15:34:57 -070016663 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16664 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16665
Wilson Yang6507c4e2013-10-01 20:11:19 -070016666 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16667 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016668 if (0 != status)
16669 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016670 return status;
16671 }
16672
16673 /*Retrieve halHandle*/
16674 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16675
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016676 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16677 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16678 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016679 /* Delete the PMKID CSR cache */
16680 if (eHAL_STATUS_SUCCESS !=
16681 sme_RoamDelPMKIDfromCache(halHandle,
16682 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16683 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16684 MAC_ADDR_ARRAY(pmksa->bssid));
16685 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016686 }
16687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016688 EXIT();
16689 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016690}
16691
Wilson Yang6507c4e2013-10-01 20:11:19 -070016692
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016693static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16694 struct cfg80211_pmksa *pmksa)
16695{
16696 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016697
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016698 vos_ssr_protect(__func__);
16699 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16700 vos_ssr_unprotect(__func__);
16701
16702 return ret;
16703
16704}
16705
16706static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016707{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016708 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16709 tHalHandle halHandle;
16710 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016711 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016712
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016713 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016714
16715 /* Validate pAdapter */
16716 if (NULL == pAdapter)
16717 {
16718 hddLog(VOS_TRACE_LEVEL_ERROR,
16719 "%s: Invalid Adapter" ,__func__);
16720 return -EINVAL;
16721 }
16722
16723 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16724 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016725 if (0 != status)
16726 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016727 return status;
16728 }
16729
16730 /*Retrieve halHandle*/
16731 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16732
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016733 /* Flush the PMKID cache in CSR */
16734 if (eHAL_STATUS_SUCCESS !=
16735 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16737 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016738 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016739 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016740 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016741}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016742
16743static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16744{
16745 int ret;
16746
16747 vos_ssr_protect(__func__);
16748 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16749 vos_ssr_unprotect(__func__);
16750
16751 return ret;
16752}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016753#endif
16754
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016755#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016756static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16757 struct net_device *dev,
16758 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016759{
16760 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16761 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016762 hdd_context_t *pHddCtx;
16763 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016764
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016765 ENTER();
16766
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016767 if (NULL == pAdapter)
16768 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016770 return -ENODEV;
16771 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016772 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16773 ret = wlan_hdd_validate_context(pHddCtx);
16774 if (0 != ret)
16775 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016776 return ret;
16777 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016778 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016779 if (NULL == pHddStaCtx)
16780 {
16781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16782 return -EINVAL;
16783 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016784
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016785 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16786 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16787 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016788 // Added for debug on reception of Re-assoc Req.
16789 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16790 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016791 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016792 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016793 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016794 }
16795
16796#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016797 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016798 ftie->ie_len);
16799#endif
16800
16801 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016802 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16803 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016804 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016805
16806 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016807 return 0;
16808}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016809
16810static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16811 struct net_device *dev,
16812 struct cfg80211_update_ft_ies_params *ftie)
16813{
16814 int ret;
16815
16816 vos_ssr_protect(__func__);
16817 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16818 vos_ssr_unprotect(__func__);
16819
16820 return ret;
16821}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016822#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016823
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016824#ifdef FEATURE_WLAN_SCAN_PNO
16825
16826void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16827 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16828{
16829 int ret;
16830 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16831 hdd_context_t *pHddCtx;
16832
Nirav Shah80830bf2013-12-31 16:35:12 +053016833 ENTER();
16834
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016835 if (NULL == pAdapter)
16836 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016838 "%s: HDD adapter is Null", __func__);
16839 return ;
16840 }
16841
16842 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16843 if (NULL == pHddCtx)
16844 {
16845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16846 "%s: HDD context is Null!!!", __func__);
16847 return ;
16848 }
16849
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016850 spin_lock(&pHddCtx->schedScan_lock);
16851 if (TRUE == pHddCtx->isWiphySuspended)
16852 {
16853 pHddCtx->isSchedScanUpdatePending = TRUE;
16854 spin_unlock(&pHddCtx->schedScan_lock);
16855 hddLog(VOS_TRACE_LEVEL_INFO,
16856 "%s: Update cfg80211 scan database after it resume", __func__);
16857 return ;
16858 }
16859 spin_unlock(&pHddCtx->schedScan_lock);
16860
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016861 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16862
16863 if (0 > ret)
16864 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016865 else
16866 {
16867 /* Acquire wakelock to handle the case where APP's tries to suspend
16868 * immediatly after the driver gets connect request(i.e after pno)
16869 * from supplicant, this result in app's is suspending and not able
16870 * to process the connect request to AP */
16871 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16872 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016873 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16875 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016876}
16877
16878/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016879 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016880 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016881 */
16882static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16883{
16884 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16885 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016886 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016887 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16888 int status = 0;
16889 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16890
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016891 /* The current firmware design does not allow PNO during any
16892 * active sessions. Hence, determine the active sessions
16893 * and return a failure.
16894 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016895 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16896 {
16897 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016898 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016899
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016900 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16901 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16902 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16903 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16904 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016905 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016906 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016907 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016908 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016909 }
16910 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16911 pAdapterNode = pNext;
16912 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016913 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016914}
16915
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016916void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16917{
16918 hdd_adapter_t *pAdapter = callbackContext;
16919 hdd_context_t *pHddCtx;
16920
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016921 ENTER();
16922
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016923 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16924 {
16925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16926 FL("Invalid adapter or adapter has invalid magic"));
16927 return;
16928 }
16929
16930 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16931 if (0 != wlan_hdd_validate_context(pHddCtx))
16932 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016933 return;
16934 }
16935
c_hpothub53c45d2014-08-18 16:53:14 +053016936 if (VOS_STATUS_SUCCESS != status)
16937 {
16938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016939 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016940 pHddCtx->isPnoEnable = FALSE;
16941 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016942
16943 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16944 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016945 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016946}
16947
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016948/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016949 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16950 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016951 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016952static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016953 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16954{
16955 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016956 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016957 hdd_context_t *pHddCtx;
16958 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016959 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016960 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16961 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016962 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16963 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016964 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016965 hdd_config_t *pConfig = NULL;
16966 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016968 ENTER();
16969
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016970 if (NULL == pAdapter)
16971 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016973 "%s: HDD adapter is Null", __func__);
16974 return -ENODEV;
16975 }
16976
16977 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016978 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016979
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016980 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016981 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016982 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016983 }
16984
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016985 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016986 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16987 if (NULL == hHal)
16988 {
16989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16990 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016991 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016992 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016993 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16994 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16995 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016996 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016997 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016998 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016999 {
17000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17001 "%s: aborting the existing scan is unsuccessfull", __func__);
17002 return -EBUSY;
17003 }
17004
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017005 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017006 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053017007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053017008 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053017009 return -EBUSY;
17010 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017011
c_hpothu37f21312014-04-09 21:49:54 +053017012 if (TRUE == pHddCtx->isPnoEnable)
17013 {
17014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17015 FL("already PNO is enabled"));
17016 return -EBUSY;
17017 }
c_hpothu225aa7c2014-10-22 17:45:13 +053017018
17019 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
17020 {
17021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17022 "%s: abort ROC failed ", __func__);
17023 return -EBUSY;
17024 }
17025
c_hpothu37f21312014-04-09 21:49:54 +053017026 pHddCtx->isPnoEnable = TRUE;
17027
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017028 pnoRequest.enable = 1; /*Enable PNO */
17029 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017030
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017031 if (( !pnoRequest.ucNetworksCount ) ||
17032 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017033 {
17034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017035 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017036 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017037 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017038 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017039 goto error;
17040 }
17041
17042 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
17043 {
17044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017045 "%s: Incorrect number of channels %d",
17046 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017047 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017048 goto error;
17049 }
17050
17051 /* Framework provides one set of channels(all)
17052 * common for all saved profile */
17053 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17054 channels_allowed, &num_channels_allowed))
17055 {
17056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17057 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017058 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017059 goto error;
17060 }
17061 /* Checking each channel against allowed channel list */
17062 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053017063 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017064 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017065 char chList [(request->n_channels*5)+1];
17066 int len;
17067 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017068 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017069 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017070 {
Nirav Shah80830bf2013-12-31 16:35:12 +053017071 if (request->channels[i]->hw_value == channels_allowed[indx])
17072 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017073 if ((!pConfig->enableDFSPnoChnlScan) &&
17074 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
17075 {
17076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17077 "%s : Dropping DFS channel : %d",
17078 __func__,channels_allowed[indx]);
17079 num_ignore_dfs_ch++;
17080 break;
17081 }
17082
Nirav Shah80830bf2013-12-31 16:35:12 +053017083 valid_ch[num_ch++] = request->channels[i]->hw_value;
17084 len += snprintf(chList+len, 5, "%d ",
17085 request->channels[i]->hw_value);
17086 break ;
17087 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017088 }
17089 }
Nirav Shah80830bf2013-12-31 16:35:12 +053017090 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017091
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053017092 /*If all channels are DFS and dropped, then ignore the PNO request*/
17093 if (num_ignore_dfs_ch == request->n_channels)
17094 {
17095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17096 "%s : All requested channels are DFS channels", __func__);
17097 ret = -EINVAL;
17098 goto error;
17099 }
17100 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017101
17102 pnoRequest.aNetworks =
17103 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17104 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017105 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017106 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17107 FL("failed to allocate memory aNetworks %u"),
17108 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17109 goto error;
17110 }
17111 vos_mem_zero(pnoRequest.aNetworks,
17112 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
17113
17114 /* Filling per profile params */
17115 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
17116 {
17117 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017118 request->match_sets[i].ssid.ssid_len;
17119
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017120 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
17121 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017122 {
17123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017124 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017125 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017126 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017127 goto error;
17128 }
17129
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017130 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017131 request->match_sets[i].ssid.ssid,
17132 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053017133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17134 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017135 i, pnoRequest.aNetworks[i].ssId.ssId);
17136 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
17137 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
17138 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017139
17140 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017141 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
17142 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017143
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017144 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017145 }
17146
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017147 for (i = 0; i < request->n_ssids; i++)
17148 {
17149 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017150 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017151 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017152 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017153 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017154 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017155 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017156 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017157 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017158 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053017159 break;
17160 }
17161 j++;
17162 }
17163 }
17164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17165 "Number of hidden networks being Configured = %d",
17166 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080017168 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017169
17170 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17171 if (pnoRequest.p24GProbeTemplate == NULL)
17172 {
17173 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17174 FL("failed to allocate memory p24GProbeTemplate %u"),
17175 SIR_PNO_MAX_PB_REQ_SIZE);
17176 goto error;
17177 }
17178
17179 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
17180 if (pnoRequest.p5GProbeTemplate == NULL)
17181 {
17182 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
17183 FL("failed to allocate memory p5GProbeTemplate %u"),
17184 SIR_PNO_MAX_PB_REQ_SIZE);
17185 goto error;
17186 }
17187
17188 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17189 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
17190
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053017191 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
17192 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017193 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017194 pnoRequest.us24GProbeTemplateLen = request->ie_len;
17195 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
17196 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017197
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017198 pnoRequest.us5GProbeTemplateLen = request->ie_len;
17199 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
17200 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053017201 }
17202
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017203 /* Driver gets only one time interval which is hardcoded in
17204 * supplicant for 10000ms. Taking power consumption into account 6 timers
17205 * will be used, Timervalue is increased exponentially i.e 10,20,40,
17206 * 80,160,320 secs. And number of scan cycle for each timer
17207 * is configurable through INI param gPNOScanTimerRepeatValue.
17208 * If it is set to 0 only one timer will be used and PNO scan cycle
17209 * will be repeated after each interval specified by supplicant
17210 * till PNO is disabled.
17211 */
17212 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017213 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017214 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017215 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017216 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
17217
17218 tempInterval = (request->interval)/1000;
17219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17220 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
17221 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017222 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017223 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017224 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017225 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017226 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017227 tempInterval *= 2;
17228 }
17229 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017230 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053017231
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017232 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017233
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017234 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017235 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17236 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017237 pAdapter->pno_req_status = 0;
17238
Nirav Shah80830bf2013-12-31 16:35:12 +053017239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17240 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017241 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
17242 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053017243
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017244 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017245 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017246 hdd_cfg80211_sched_scan_done_callback, pAdapter);
17247 if (eHAL_STATUS_SUCCESS != status)
17248 {
17249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053017250 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017251 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017252 goto error;
17253 }
17254
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017255 ret = wait_for_completion_timeout(
17256 &pAdapter->pno_comp_var,
17257 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17258 if (0 >= ret)
17259 {
17260 // Did not receive the response for PNO enable in time.
17261 // Assuming the PNO enable was success.
17262 // Returning error from here, because we timeout, results
17263 // in side effect of Wifi (Wifi Setting) not to work.
17264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17265 FL("Timed out waiting for PNO to be Enabled"));
17266 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017267 }
17268
17269 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053017270 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017271
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017272error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17274 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053017275 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017276 if (pnoRequest.aNetworks)
17277 vos_mem_free(pnoRequest.aNetworks);
17278 if (pnoRequest.p24GProbeTemplate)
17279 vos_mem_free(pnoRequest.p24GProbeTemplate);
17280 if (pnoRequest.p5GProbeTemplate)
17281 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017282
17283 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017284 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017285}
17286
17287/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017288 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
17289 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017290 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017291static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
17292 struct net_device *dev, struct cfg80211_sched_scan_request *request)
17293{
17294 int ret;
17295
17296 vos_ssr_protect(__func__);
17297 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
17298 vos_ssr_unprotect(__func__);
17299
17300 return ret;
17301}
17302
17303/*
17304 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
17305 * Function to disable PNO
17306 */
17307static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017308 struct net_device *dev)
17309{
17310 eHalStatus status = eHAL_STATUS_FAILURE;
17311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17312 hdd_context_t *pHddCtx;
17313 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017314 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017315 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017316
17317 ENTER();
17318
17319 if (NULL == pAdapter)
17320 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017322 "%s: HDD adapter is Null", __func__);
17323 return -ENODEV;
17324 }
17325
17326 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017327
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017328 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017329 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017331 "%s: HDD context is Null", __func__);
17332 return -ENODEV;
17333 }
17334
17335 /* The return 0 is intentional when isLogpInProgress and
17336 * isLoadUnloadInProgress. We did observe a crash due to a return of
17337 * failure in sched_scan_stop , especially for a case where the unload
17338 * of the happens at the same time. The function __cfg80211_stop_sched_scan
17339 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
17340 * success. If it returns a failure , then its next invocation due to the
17341 * clean up of the second interface will have the dev pointer corresponding
17342 * to the first one leading to a crash.
17343 */
17344 if (pHddCtx->isLogpInProgress)
17345 {
17346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17347 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053017348 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017349 return ret;
17350 }
17351
Mihir Shete18156292014-03-11 15:38:30 +053017352 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017353 {
17354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17355 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17356 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017357 }
17358
17359 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17360 if (NULL == hHal)
17361 {
17362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17363 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017364 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017365 }
17366
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017367 pnoRequest.enable = 0; /* Disable PNO */
17368 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017369
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017370 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17371 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17372 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017373
17374 INIT_COMPLETION(pAdapter->pno_comp_var);
17375 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
17376 pnoRequest.callbackContext = pAdapter;
17377 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017378 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017379 pAdapter->sessionId,
17380 NULL, pAdapter);
17381 if (eHAL_STATUS_SUCCESS != status)
17382 {
17383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17384 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017385 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017386 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017387 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017388 ret = wait_for_completion_timeout(
17389 &pAdapter->pno_comp_var,
17390 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
17391 if (0 >= ret)
17392 {
17393 // Did not receive the response for PNO disable in time.
17394 // Assuming the PNO disable was success.
17395 // Returning error from here, because we timeout, results
17396 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053017397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053017398 FL("Timed out waiting for PNO to be disabled"));
17399 ret = 0;
17400 }
17401
17402 ret = pAdapter->pno_req_status;
17403 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017404
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017405error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017407 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017408
17409 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017410 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017411}
17412
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017413/*
17414 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17415 * NL interface to disable PNO
17416 */
17417static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17418 struct net_device *dev)
17419{
17420 int ret;
17421
17422 vos_ssr_protect(__func__);
17423 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17424 vos_ssr_unprotect(__func__);
17425
17426 return ret;
17427}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017428#endif /*FEATURE_WLAN_SCAN_PNO*/
17429
17430
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017431#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017432#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017433static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17434 struct net_device *dev,
17435 u8 *peer, u8 action_code,
17436 u8 dialog_token,
17437 u16 status_code, u32 peer_capability,
17438 const u8 *buf, size_t len)
17439#else /* TDLS_MGMT_VERSION2 */
17440#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17441static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17442 struct net_device *dev,
17443 const u8 *peer, u8 action_code,
17444 u8 dialog_token, u16 status_code,
17445 u32 peer_capability, bool initiator,
17446 const u8 *buf, size_t len)
17447#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17448static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17449 struct net_device *dev,
17450 const u8 *peer, u8 action_code,
17451 u8 dialog_token, u16 status_code,
17452 u32 peer_capability, const u8 *buf,
17453 size_t len)
17454#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17455static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17456 struct net_device *dev,
17457 u8 *peer, u8 action_code,
17458 u8 dialog_token,
17459 u16 status_code, u32 peer_capability,
17460 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017461#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017462static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17463 struct net_device *dev,
17464 u8 *peer, u8 action_code,
17465 u8 dialog_token,
17466 u16 status_code, const u8 *buf,
17467 size_t len)
17468#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017469#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017470{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017471 hdd_adapter_t *pAdapter;
17472 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017473 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017474 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017475 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017476 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017477 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017478 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017479#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017480 u32 peer_capability = 0;
17481#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017482 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017483 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017484
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017485 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17486 if (NULL == pAdapter)
17487 {
17488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17489 "%s: Adapter is NULL",__func__);
17490 return -EINVAL;
17491 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17493 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17494 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017495
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017496 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017497 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017498 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017500 "Invalid arguments");
17501 return -EINVAL;
17502 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017503
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017504 if (pHddCtx->isLogpInProgress)
17505 {
17506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17507 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017508 wlan_hdd_tdls_set_link_status(pAdapter,
17509 peer,
17510 eTDLS_LINK_IDLE,
17511 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017512 return -EBUSY;
17513 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017514
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017515 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17516 {
17517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17518 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17519 return -EAGAIN;
17520 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017521
Hoonki Lee27511902013-03-14 18:19:06 -070017522 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017523 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017525 "%s: TDLS mode is disabled OR not enabled in FW."
17526 MAC_ADDRESS_STR " action %d declined.",
17527 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017528 return -ENOTSUPP;
17529 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017530
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017531 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17532
17533 if( NULL == pHddStaCtx )
17534 {
17535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17536 "%s: HDD station context NULL ",__func__);
17537 return -EINVAL;
17538 }
17539
17540 /* STA should be connected and authenticated
17541 * before sending any TDLS frames
17542 */
17543 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17544 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17545 {
17546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17547 "STA is not connected or unauthenticated. "
17548 "connState %u, uIsAuthenticated %u",
17549 pHddStaCtx->conn_info.connState,
17550 pHddStaCtx->conn_info.uIsAuthenticated);
17551 return -EAGAIN;
17552 }
17553
Hoonki Lee27511902013-03-14 18:19:06 -070017554 /* other than teardown frame, other mgmt frames are not sent if disabled */
17555 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17556 {
17557 /* if tdls_mode is disabled to respond to peer's request */
17558 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17559 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017561 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017562 " TDLS mode is disabled. action %d declined.",
17563 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017564
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017565 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017566 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017567
17568 if (vos_max_concurrent_connections_reached())
17569 {
17570 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17571 return -EINVAL;
17572 }
Hoonki Lee27511902013-03-14 18:19:06 -070017573 }
17574
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017575 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17576 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017577 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017578 {
17579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017580 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017581 " TDLS setup is ongoing. action %d declined.",
17582 __func__, MAC_ADDR_ARRAY(peer), action_code);
17583 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017584 }
17585 }
17586
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017587 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17588 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017589 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017590 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17591 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017592 {
17593 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17594 we return error code at 'add_station()'. Hence we have this
17595 check again in addtion to add_station().
17596 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017597 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017598 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17600 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017601 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17602 __func__, MAC_ADDR_ARRAY(peer), action_code,
17603 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017604 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017605 }
17606 else
17607 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017608 /* maximum reached. tweak to send error code to peer and return
17609 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017610 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17612 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017613 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17614 __func__, MAC_ADDR_ARRAY(peer), status_code,
17615 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017616 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017617 /* fall through to send setup resp with failure status
17618 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017619 }
17620 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017621 else
17622 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017623 mutex_lock(&pHddCtx->tdls_lock);
17624 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017625 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017626 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017627 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017629 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17630 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017631 return -EPERM;
17632 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017633 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017634 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017635 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017636
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017638 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017639 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17640 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017641
Hoonki Leea34dd892013-02-05 22:56:02 -080017642 /*Except teardown responder will not be used so just make 0*/
17643 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017644 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017645 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017646
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017647 mutex_lock(&pHddCtx->tdls_lock);
17648 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017649
17650 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17651 responder = pTdlsPeer->is_responder;
17652 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017653 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017655 "%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 -070017656 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17657 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017658 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017659 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017660 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017661 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017662 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017663
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017664 /* Discard TDLS setup if peer is removed by user app */
17665 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17666 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17667 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17668 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17669
17670 mutex_lock(&pHddCtx->tdls_lock);
17671 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17672 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17673 mutex_unlock(&pHddCtx->tdls_lock);
17674 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17675 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17676 MAC_ADDR_ARRAY(peer), action_code);
17677 return -EINVAL;
17678 }
17679 mutex_unlock(&pHddCtx->tdls_lock);
17680 }
17681
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017682 /* For explicit trigger of DIS_REQ come out of BMPS for
17683 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017684 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053017685 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017686 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17687 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017688 {
17689 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17690 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017692 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017693 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17694 if (status != VOS_STATUS_SUCCESS) {
17695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17696 }
Hoonki Lee14621352013-04-16 17:51:19 -070017697 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017698 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017699 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017700 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17701 }
17702 }
Hoonki Lee14621352013-04-16 17:51:19 -070017703 }
17704
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017705 /* make sure doesn't call send_mgmt() while it is pending */
17706 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17707 {
17708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017709 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017710 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017711 ret = -EBUSY;
17712 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017713 }
17714
17715 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017716 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17717
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017718 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17719 pAdapter->sessionId, peer, action_code, dialog_token,
17720 status_code, peer_capability, (tANI_U8 *)buf, len,
17721 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017722
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017723 if (VOS_STATUS_SUCCESS != status)
17724 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17726 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017727 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017728 ret = -EINVAL;
17729 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017730 }
17731
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17733 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17734 WAIT_TIME_TDLS_MGMT);
17735
Hoonki Leed37cbb32013-04-20 00:31:14 -070017736 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17737 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17738
17739 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017740 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017742 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017743 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017744 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017745
17746 if (pHddCtx->isLogpInProgress)
17747 {
17748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17749 "%s: LOGP in Progress. Ignore!!!", __func__);
17750 return -EAGAIN;
17751 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017752 if (rc <= 0)
17753 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17754 WLAN_LOG_INDICATOR_HOST_DRIVER,
17755 WLAN_LOG_REASON_HDD_TIME_OUT,
17756 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017757
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017758 ret = -EINVAL;
17759 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017760 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017761 else
17762 {
17763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17764 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17765 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17766 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017767
Gopichand Nakkala05922802013-03-14 12:23:19 -070017768 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017769 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017770 ret = max_sta_failed;
17771 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017772 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017773
Hoonki Leea34dd892013-02-05 22:56:02 -080017774 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17775 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017776 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17778 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017779 }
17780 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17781 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017782 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17784 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017785 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017786
17787 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017788
17789tx_failed:
17790 /* add_station will be called before sending TDLS_SETUP_REQ and
17791 * TDLS_SETUP_RSP and as part of add_station driver will enable
17792 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17793 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17794 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17795 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17796 */
17797
17798 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17799 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17800 wlan_hdd_tdls_check_bmps(pAdapter);
17801 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017802}
17803
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017804#if TDLS_MGMT_VERSION2
17805static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17806 u8 *peer, u8 action_code, u8 dialog_token,
17807 u16 status_code, u32 peer_capability,
17808 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017809#else /* TDLS_MGMT_VERSION2 */
17810#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17811static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17812 struct net_device *dev,
17813 const u8 *peer, u8 action_code,
17814 u8 dialog_token, u16 status_code,
17815 u32 peer_capability, bool initiator,
17816 const u8 *buf, size_t len)
17817#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17818static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17819 struct net_device *dev,
17820 const u8 *peer, u8 action_code,
17821 u8 dialog_token, u16 status_code,
17822 u32 peer_capability, const u8 *buf,
17823 size_t len)
17824#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17825static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17826 struct net_device *dev,
17827 u8 *peer, u8 action_code,
17828 u8 dialog_token,
17829 u16 status_code, u32 peer_capability,
17830 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017831#else
17832static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17833 u8 *peer, u8 action_code, u8 dialog_token,
17834 u16 status_code, const u8 *buf, size_t len)
17835#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017836#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017837{
17838 int ret;
17839
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017840 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017841#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017842 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17843 dialog_token, status_code,
17844 peer_capability, buf, len);
17845#else /* TDLS_MGMT_VERSION2 */
17846#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17847 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17848 dialog_token, status_code,
17849 peer_capability, initiator,
17850 buf, len);
17851#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17852 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17853 dialog_token, status_code,
17854 peer_capability, buf, len);
17855#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17856 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17857 dialog_token, status_code,
17858 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017859#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017860 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17861 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017862#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017863#endif
17864 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017865
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017866 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017867}
Atul Mittal115287b2014-07-08 13:26:33 +053017868
17869int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17871 const u8 *peer,
17872#else
Atul Mittal115287b2014-07-08 13:26:33 +053017873 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017874#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017875 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017876 cfg80211_exttdls_callback callback)
17877{
17878
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017879 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017880 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017881 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17883 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17884 __func__, MAC_ADDR_ARRAY(peer));
17885
17886 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17887 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17888
17889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017890 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17891 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17892 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017893 return -ENOTSUPP;
17894 }
17895
17896 /* To cater the requirement of establishing the TDLS link
17897 * irrespective of the data traffic , get an entry of TDLS peer.
17898 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017899 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017900 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17901 if (pTdlsPeer == NULL) {
17902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17903 "%s: peer " MAC_ADDRESS_STR " not existing",
17904 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017905 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017906 return -EINVAL;
17907 }
17908
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017909 /* check FW TDLS Off Channel capability */
17910 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017911 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017912 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017913 {
17914 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17915 pTdlsPeer->peerParams.global_operating_class =
17916 tdls_peer_params->global_operating_class;
17917 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17918 pTdlsPeer->peerParams.min_bandwidth_kbps =
17919 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017920 /* check configured channel is valid, non dfs and
17921 * not current operating channel */
17922 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17923 tdls_peer_params->channel)) &&
17924 (pHddStaCtx) &&
17925 (tdls_peer_params->channel !=
17926 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017927 {
17928 pTdlsPeer->isOffChannelConfigured = TRUE;
17929 }
17930 else
17931 {
17932 pTdlsPeer->isOffChannelConfigured = FALSE;
17933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17934 "%s: Configured Tdls Off Channel is not valid", __func__);
17935
17936 }
17937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017938 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17939 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017940 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017941 pTdlsPeer->isOffChannelConfigured,
17942 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017943 }
17944 else
17945 {
17946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017947 "%s: TDLS off channel FW capability %d, "
17948 "host capab %d or Invalid TDLS Peer Params", __func__,
17949 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17950 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017951 }
17952
Atul Mittal115287b2014-07-08 13:26:33 +053017953 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17954
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017955 mutex_unlock(&pHddCtx->tdls_lock);
17956
Atul Mittal115287b2014-07-08 13:26:33 +053017957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17958 " %s TDLS Add Force Peer Failed",
17959 __func__);
17960 return -EINVAL;
17961 }
17962 /*EXT TDLS*/
17963
17964 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017965 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17967 " %s TDLS set callback Failed",
17968 __func__);
17969 return -EINVAL;
17970 }
17971
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017972 mutex_unlock(&pHddCtx->tdls_lock);
17973
Atul Mittal115287b2014-07-08 13:26:33 +053017974 return(0);
17975
17976}
17977
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017978int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17980 const u8 *peer
17981#else
17982 u8 *peer
17983#endif
17984)
Atul Mittal115287b2014-07-08 13:26:33 +053017985{
17986
17987 hddTdlsPeer_t *pTdlsPeer;
17988 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053017989
Atul Mittal115287b2014-07-08 13:26:33 +053017990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17991 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17992 __func__, MAC_ADDR_ARRAY(peer));
17993
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017994 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17996 return -EINVAL;
17997 }
17998
Atul Mittal115287b2014-07-08 13:26:33 +053017999 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
18000 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
18001
18002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018003 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
18004 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
18005 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053018006 return -ENOTSUPP;
18007 }
18008
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018009 mutex_lock(&pHddCtx->tdls_lock);
18010 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053018011
18012 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018013 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018015 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053018016 __func__, MAC_ADDR_ARRAY(peer));
18017 return -EINVAL;
18018 }
18019 else {
18020 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
18021 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053018022 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
18023 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018024 /* if channel switch is configured, reset
18025 the channel for this peer */
18026 if (TRUE == pTdlsPeer->isOffChannelConfigured)
18027 {
18028 pTdlsPeer->peerParams.channel = 0;
18029 pTdlsPeer->isOffChannelConfigured = FALSE;
18030 }
Atul Mittal115287b2014-07-08 13:26:33 +053018031 }
18032
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018033 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018034 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018035 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053018036 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018037 }
Atul Mittal115287b2014-07-08 13:26:33 +053018038
18039 /*EXT TDLS*/
18040
18041 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018042 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053018043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18044 " %s TDLS set callback Failed",
18045 __func__);
18046 return -EINVAL;
18047 }
Atul Mittal115287b2014-07-08 13:26:33 +053018048
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018049 mutex_unlock(&pHddCtx->tdls_lock);
18050
18051 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053018052}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018053static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18055 const u8 *peer,
18056#else
18057 u8 *peer,
18058#endif
18059 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018060{
18061 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18062 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018063 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018064 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018065
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018066 ENTER();
18067
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053018068 if (!pAdapter) {
18069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
18070 return -EINVAL;
18071 }
18072
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18074 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
18075 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018076 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018077 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070018079 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018080 return -EINVAL;
18081 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018082
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018083 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018084 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018085 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018086 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080018087 }
18088
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018089
18090 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018091 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018092 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080018093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018094 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
18095 "Cannot process TDLS commands",
18096 pHddCtx->cfg_ini->fEnableTDLSSupport,
18097 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018098 return -ENOTSUPP;
18099 }
18100
18101 switch (oper) {
18102 case NL80211_TDLS_ENABLE_LINK:
18103 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018104 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018105 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053018106 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
18107 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053018108 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018109 tANI_U16 numCurrTdlsPeers = 0;
18110 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018111 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018112 tSirMacAddr peerMac;
18113 int channel;
18114 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018115
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18117 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
18118 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018119
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018120 mutex_lock(&pHddCtx->tdls_lock);
18121 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018122 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053018123 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018124 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018125 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18126 " (oper %d) not exsting. ignored",
18127 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18128 return -EINVAL;
18129 }
18130
18131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18132 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18133 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18134 "NL80211_TDLS_ENABLE_LINK");
18135
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018136 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
18137 {
18138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
18139 MAC_ADDRESS_STR " failed",
18140 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018141 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070018142 return -EINVAL;
18143 }
18144
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018145 /* before starting tdls connection, set tdls
18146 * off channel established status to default value */
18147 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018148
18149 mutex_unlock(&pHddCtx->tdls_lock);
18150
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053018151 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018152 /* TDLS Off Channel, Disable tdls channel switch,
18153 when there are more than one tdls link */
18154 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053018155 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018156 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018157 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018158 /* get connected peer and send disable tdls off chan */
18159 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018160 if ((connPeer) &&
18161 (connPeer->isOffChannelSupported == TRUE) &&
18162 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018163 {
18164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18165 "%s: More then one peer connected, Disable "
18166 "TDLS channel switch", __func__);
18167
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018168 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018169 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
18170 channel = connPeer->peerParams.channel;
18171
18172 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018173
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018174 ret = sme_SendTdlsChanSwitchReq(
18175 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018176 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018177 peerMac,
18178 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018179 TDLS_OFF_CHANNEL_BW_OFFSET,
18180 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018181 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018182 hddLog(VOS_TRACE_LEVEL_ERROR,
18183 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018184 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018185 }
18186 else
18187 {
18188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18189 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018190 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018191 "isOffChannelConfigured %d",
18192 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018193 (connPeer ? (connPeer->isOffChannelSupported)
18194 : -1),
18195 (connPeer ? (connPeer->isOffChannelConfigured)
18196 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018197 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018198 }
18199 }
18200
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018201 mutex_lock(&pHddCtx->tdls_lock);
18202 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18203 if ( NULL == pTdlsPeer ) {
18204 mutex_unlock(&pHddCtx->tdls_lock);
18205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18206 "%s: " MAC_ADDRESS_STR
18207 " (oper %d) peer got freed in other context. ignored",
18208 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18209 return -EINVAL;
18210 }
18211 peer_status = pTdlsPeer->link_status;
18212 mutex_unlock(&pHddCtx->tdls_lock);
18213
18214 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018215 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018216 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053018217
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018218 if (0 != wlan_hdd_tdls_get_link_establish_params(
18219 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018220 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018221 return -EINVAL;
18222 }
18223 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018224
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018225 ret = sme_SendTdlsLinkEstablishParams(
18226 WLAN_HDD_GET_HAL_CTX(pAdapter),
18227 pAdapter->sessionId, peer,
18228 &tdlsLinkEstablishParams);
18229 if (ret != VOS_STATUS_SUCCESS) {
18230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
18231 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018232 /* Send TDLS peer UAPSD capabilities to the firmware and
18233 * register with the TL on after the response for this operation
18234 * is received .
18235 */
18236 ret = wait_for_completion_interruptible_timeout(
18237 &pAdapter->tdls_link_establish_req_comp,
18238 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053018239
18240 mutex_lock(&pHddCtx->tdls_lock);
18241 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18242 if ( NULL == pTdlsPeer ) {
18243 mutex_unlock(&pHddCtx->tdls_lock);
18244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18245 "%s %d: " MAC_ADDRESS_STR
18246 " (oper %d) peer got freed in other context. ignored",
18247 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
18248 (int)oper);
18249 return -EINVAL;
18250 }
18251 peer_status = pTdlsPeer->link_status;
18252 mutex_unlock(&pHddCtx->tdls_lock);
18253
18254 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018255 {
18256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018257 FL("Link Establish Request Failed Status %ld"),
18258 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053018259 return -EINVAL;
18260 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018261 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053018262
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018263 mutex_lock(&pHddCtx->tdls_lock);
18264 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18265 if ( NULL == pTdlsPeer ) {
18266 mutex_unlock(&pHddCtx->tdls_lock);
18267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18268 "%s: " MAC_ADDRESS_STR
18269 " (oper %d) peer got freed in other context. ignored",
18270 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18271 return -EINVAL;
18272 }
18273
Atul Mittal115287b2014-07-08 13:26:33 +053018274 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18275 eTDLS_LINK_CONNECTED,
18276 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053018277 staDesc.ucSTAId = pTdlsPeer->staId;
18278 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053018279
18280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18281 "%s: tdlsLinkEstablishParams of peer "
18282 MAC_ADDRESS_STR "uapsdQueues: %d"
18283 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
18284 "isResponder: %d peerstaId: %d",
18285 __func__,
18286 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
18287 tdlsLinkEstablishParams.uapsdQueues,
18288 tdlsLinkEstablishParams.qos,
18289 tdlsLinkEstablishParams.maxSp,
18290 tdlsLinkEstablishParams.isBufSta,
18291 tdlsLinkEstablishParams.isOffChannelSupported,
18292 tdlsLinkEstablishParams.isResponder,
18293 pTdlsPeer->staId);
18294
18295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18296 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
18297 __func__,
18298 staDesc.ucSTAId,
18299 staDesc.ucQosEnabled);
18300
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018301 ret = WLANTL_UpdateTdlsSTAClient(
18302 pHddCtx->pvosContext,
18303 &staDesc);
18304 if (ret != VOS_STATUS_SUCCESS) {
18305 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
18306 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053018307
Gopichand Nakkala471708b2013-06-04 20:03:01 +053018308 /* Mark TDLS client Authenticated .*/
18309 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
18310 pTdlsPeer->staId,
18311 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018312 if (VOS_STATUS_SUCCESS == status)
18313 {
Hoonki Lee14621352013-04-16 17:51:19 -070018314 if (pTdlsPeer->is_responder == 0)
18315 {
18316 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018317 tdlsConnInfo_t *tdlsInfo;
18318
18319 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
18320
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018321 if (!vos_timer_is_initialized(
18322 &pTdlsPeer->initiatorWaitTimeoutTimer))
18323 {
18324 /* Initialize initiator wait callback */
18325 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053018326 &pTdlsPeer->initiatorWaitTimeoutTimer,
18327 VOS_TIMER_TYPE_SW,
18328 wlan_hdd_tdls_initiator_wait_cb,
18329 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053018330 }
Hoonki Lee14621352013-04-16 17:51:19 -070018331 wlan_hdd_tdls_timer_restart(pAdapter,
18332 &pTdlsPeer->initiatorWaitTimeoutTimer,
18333 WAIT_TIME_TDLS_INITIATOR);
18334 /* suspend initiator TX until it receives direct packet from the
18335 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018336 ret = WLANTL_SuspendDataTx(
18337 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18338 &staId, NULL);
18339 if (ret != VOS_STATUS_SUCCESS) {
18340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
18341 }
Hoonki Lee14621352013-04-16 17:51:19 -070018342 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018343
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018344 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018345 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018346 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018347 suppChannelLen =
18348 tdlsLinkEstablishParams.supportedChannelsLen;
18349
18350 if ((suppChannelLen > 0) &&
18351 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
18352 {
18353 tANI_U8 suppPeerChannel = 0;
18354 int i = 0;
18355 for (i = 0U; i < suppChannelLen; i++)
18356 {
18357 suppPeerChannel =
18358 tdlsLinkEstablishParams.supportedChannels[i];
18359
18360 pTdlsPeer->isOffChannelSupported = FALSE;
18361 if (suppPeerChannel ==
18362 pTdlsPeer->peerParams.channel)
18363 {
18364 pTdlsPeer->isOffChannelSupported = TRUE;
18365 break;
18366 }
18367 }
18368 }
18369 else
18370 {
18371 pTdlsPeer->isOffChannelSupported = FALSE;
18372 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018373 }
18374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18375 "%s: TDLS channel switch request for channel "
18376 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018377 "%d isOffChannelSupported %d", __func__,
18378 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018379 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053018380 suppChannelLen,
18381 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053018382
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018383 /* TDLS Off Channel, Enable tdls channel switch,
18384 when their is only one tdls link and it supports */
18385 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18386 if ((numCurrTdlsPeers == 1) &&
18387 (TRUE == pTdlsPeer->isOffChannelSupported) &&
18388 (TRUE == pTdlsPeer->isOffChannelConfigured))
18389 {
18390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18391 "%s: Send TDLS channel switch request for channel %d",
18392 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018393
18394 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018395 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
18396 channel = pTdlsPeer->peerParams.channel;
18397
18398 mutex_unlock(&pHddCtx->tdls_lock);
18399
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018400 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
18401 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018402 peerMac,
18403 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018404 TDLS_OFF_CHANNEL_BW_OFFSET,
18405 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018406 if (ret != VOS_STATUS_SUCCESS) {
18407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
18408 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018409 }
18410 else
18411 {
18412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18413 "%s: TDLS channel switch request not sent"
18414 " numCurrTdlsPeers %d "
18415 "isOffChannelSupported %d "
18416 "isOffChannelConfigured %d",
18417 __func__, numCurrTdlsPeers,
18418 pTdlsPeer->isOffChannelSupported,
18419 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018420 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018421 }
18422
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070018423 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018424 else
18425 mutex_unlock(&pHddCtx->tdls_lock);
18426
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018427 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018428
18429 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018430 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
18431 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018432 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018433 int ac;
18434 uint8 ucAc[4] = { WLANTL_AC_VO,
18435 WLANTL_AC_VI,
18436 WLANTL_AC_BK,
18437 WLANTL_AC_BE };
18438 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
18439 for(ac=0; ac < 4; ac++)
18440 {
18441 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
18442 pTdlsPeer->staId, ucAc[ac],
18443 tlTid[ac], tlTid[ac], 0, 0,
18444 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018445 if (status != VOS_STATUS_SUCCESS) {
18446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
18447 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053018448 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053018449 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018450 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053018451
Bhargav Shah66896792015-10-01 18:17:37 +053018452 /* stop TCP delack timer if TDLS is enable */
18453 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18454 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053018455 hdd_wlan_tdls_enable_link_event(peer,
18456 pTdlsPeer->isOffChannelSupported,
18457 pTdlsPeer->isOffChannelConfigured,
18458 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018459 }
18460 break;
18461 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080018462 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018463 tANI_U16 numCurrTdlsPeers = 0;
18464 hddTdlsPeer_t *connPeer = NULL;
18465
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18467 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
18468 __func__, MAC_ADDR_ARRAY(peer));
18469
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018470 mutex_lock(&pHddCtx->tdls_lock);
18471 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018472
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018473
Sunil Dutt41de4e22013-11-14 18:09:02 +053018474 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018475 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18477 " (oper %d) not exsting. ignored",
18478 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18479 return -EINVAL;
18480 }
18481
18482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18483 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18484 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18485 "NL80211_TDLS_DISABLE_LINK");
18486
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018487 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018488 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018489 long status;
18490
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018491 /* set tdls off channel status to false for this peer */
18492 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018493 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18494 eTDLS_LINK_TEARING,
18495 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18496 eTDLS_LINK_UNSPECIFIED:
18497 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018498 mutex_unlock(&pHddCtx->tdls_lock);
18499
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018500 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18501
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018502 status = sme_DeleteTdlsPeerSta(
18503 WLAN_HDD_GET_HAL_CTX(pAdapter),
18504 pAdapter->sessionId, peer );
18505 if (status != VOS_STATUS_SUCCESS) {
18506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18507 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018508
18509 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18510 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018511
18512 mutex_lock(&pHddCtx->tdls_lock);
18513 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18514 if ( NULL == pTdlsPeer ) {
18515 mutex_unlock(&pHddCtx->tdls_lock);
18516 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18517 " peer was freed in other context",
18518 __func__, MAC_ADDR_ARRAY(peer));
18519 return -EINVAL;
18520 }
18521
Atul Mittal271a7652014-09-12 13:18:22 +053018522 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018523 eTDLS_LINK_IDLE,
18524 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018525 mutex_unlock(&pHddCtx->tdls_lock);
18526
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018527 if (status <= 0)
18528 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18530 "%s: Del station failed status %ld",
18531 __func__, status);
18532 return -EPERM;
18533 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018534
18535 /* TDLS Off Channel, Enable tdls channel switch,
18536 when their is only one tdls link and it supports */
18537 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18538 if (numCurrTdlsPeers == 1)
18539 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018540 tSirMacAddr peerMac;
18541 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018542
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018543 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018544 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018545
18546 if (connPeer == NULL) {
18547 mutex_unlock(&pHddCtx->tdls_lock);
18548 hddLog(VOS_TRACE_LEVEL_ERROR,
18549 "%s connPeer is NULL", __func__);
18550 return -EINVAL;
18551 }
18552
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018553 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18554 channel = connPeer->peerParams.channel;
18555
18556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18557 "%s: TDLS channel switch "
18558 "isOffChannelSupported %d "
18559 "isOffChannelConfigured %d "
18560 "isOffChannelEstablished %d",
18561 __func__,
18562 (connPeer ? connPeer->isOffChannelSupported : -1),
18563 (connPeer ? connPeer->isOffChannelConfigured : -1),
18564 (connPeer ? connPeer->isOffChannelEstablished : -1));
18565
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018566 if ((connPeer) &&
18567 (connPeer->isOffChannelSupported == TRUE) &&
18568 (connPeer->isOffChannelConfigured == TRUE))
18569 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018570 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018571 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018572 status = sme_SendTdlsChanSwitchReq(
18573 WLAN_HDD_GET_HAL_CTX(pAdapter),
18574 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018575 peerMac,
18576 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018577 TDLS_OFF_CHANNEL_BW_OFFSET,
18578 TDLS_CHANNEL_SWITCH_ENABLE);
18579 if (status != VOS_STATUS_SUCCESS) {
18580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18581 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018582 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018583 else
18584 mutex_unlock(&pHddCtx->tdls_lock);
18585 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018586 else
18587 {
18588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18589 "%s: TDLS channel switch request not sent "
18590 "numCurrTdlsPeers %d ",
18591 __func__, numCurrTdlsPeers);
18592 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018593 }
18594 else
18595 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018596 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18598 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018599 }
Bhargav Shah66896792015-10-01 18:17:37 +053018600 if (numCurrTdlsPeers == 0) {
18601 /* start TCP delack timer if TDLS is disable */
18602 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
18603 hdd_manage_delack_timer(pHddCtx);
18604 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018605 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018606 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018607 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018608 {
Atul Mittal115287b2014-07-08 13:26:33 +053018609 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018610
Atul Mittal115287b2014-07-08 13:26:33 +053018611 if (0 != status)
18612 {
18613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018614 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018615 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018616 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018617 break;
18618 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018619 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018620 {
Atul Mittal115287b2014-07-08 13:26:33 +053018621 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18622 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018623 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018624 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018625
Atul Mittal115287b2014-07-08 13:26:33 +053018626 if (0 != status)
18627 {
18628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018629 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018630 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018631 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018632 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018633 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018634 case NL80211_TDLS_DISCOVERY_REQ:
18635 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018637 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018638 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018639 return -ENOTSUPP;
18640 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18642 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018643 return -ENOTSUPP;
18644 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018645
18646 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018647 return 0;
18648}
Chilam NG571c65a2013-01-19 12:27:36 +053018649
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018650static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018651#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18652 const u8 *peer,
18653#else
18654 u8 *peer,
18655#endif
18656 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018657{
18658 int ret;
18659
18660 vos_ssr_protect(__func__);
18661 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18662 vos_ssr_unprotect(__func__);
18663
18664 return ret;
18665}
18666
Chilam NG571c65a2013-01-19 12:27:36 +053018667int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18668 struct net_device *dev, u8 *peer)
18669{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018670 hddLog(VOS_TRACE_LEVEL_INFO,
18671 "tdls send discover req: "MAC_ADDRESS_STR,
18672 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018673#if TDLS_MGMT_VERSION2
18674 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18675 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18676#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018677#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18678 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18679 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18680#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18681 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18682 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18683#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18684 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18685 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18686#else
Chilam NG571c65a2013-01-19 12:27:36 +053018687 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18688 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018689#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018690#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018691}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018692#endif
18693
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018694#ifdef WLAN_FEATURE_GTK_OFFLOAD
18695/*
18696 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18697 * Callback rountine called upon receiving response for
18698 * get offload info
18699 */
18700void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18701 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18702{
18703
18704 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018705 tANI_U8 tempReplayCounter[8];
18706 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018707
18708 ENTER();
18709
18710 if (NULL == pAdapter)
18711 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018713 "%s: HDD adapter is Null", __func__);
18714 return ;
18715 }
18716
18717 if (NULL == pGtkOffloadGetInfoRsp)
18718 {
18719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18720 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18721 return ;
18722 }
18723
18724 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18725 {
18726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18727 "%s: wlan Failed to get replay counter value",
18728 __func__);
18729 return ;
18730 }
18731
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018732 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18733 /* Update replay counter */
18734 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18735 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18736
18737 {
18738 /* changing from little to big endian since supplicant
18739 * works on big endian format
18740 */
18741 int i;
18742 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18743
18744 for (i = 0; i < 8; i++)
18745 {
18746 tempReplayCounter[7-i] = (tANI_U8)p[i];
18747 }
18748 }
18749
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018750 /* Update replay counter to NL */
18751 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018752 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018753}
18754
18755/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018756 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018757 * This function is used to offload GTK rekeying job to the firmware.
18758 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018759int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018760 struct cfg80211_gtk_rekey_data *data)
18761{
18762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18763 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18764 hdd_station_ctx_t *pHddStaCtx;
18765 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018766 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018767 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018768 eHalStatus status = eHAL_STATUS_FAILURE;
18769
18770 ENTER();
18771
18772 if (NULL == pAdapter)
18773 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018775 "%s: HDD adapter is Null", __func__);
18776 return -ENODEV;
18777 }
18778
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018779 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18780 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18781 pAdapter->sessionId, pAdapter->device_mode));
18782
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018783 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018784 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018785 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018786 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018787 }
18788
18789 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18790 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18791 if (NULL == hHal)
18792 {
18793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18794 "%s: HAL context is Null!!!", __func__);
18795 return -EAGAIN;
18796 }
18797
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018798 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18799 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18800 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18801 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018802 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018803 {
18804 /* changing from big to little endian since driver
18805 * works on little endian format
18806 */
18807 tANI_U8 *p =
18808 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18809 int i;
18810
18811 for (i = 0; i < 8; i++)
18812 {
18813 p[7-i] = data->replay_ctr[i];
18814 }
18815 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018816
18817 if (TRUE == pHddCtx->hdd_wlan_suspended)
18818 {
18819 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018820 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18821 sizeof (tSirGtkOffloadParams));
18822 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018823 pAdapter->sessionId);
18824
18825 if (eHAL_STATUS_SUCCESS != status)
18826 {
18827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18828 "%s: sme_SetGTKOffload failed, returned %d",
18829 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018830
18831 /* Need to clear any trace of key value in the memory.
18832 * Thus zero out the memory even though it is local
18833 * variable.
18834 */
18835 vos_mem_zero(&hddGtkOffloadReqParams,
18836 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018837 return status;
18838 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18840 "%s: sme_SetGTKOffload successfull", __func__);
18841 }
18842 else
18843 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18845 "%s: wlan not suspended GTKOffload request is stored",
18846 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018847 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018848
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018849 /* Need to clear any trace of key value in the memory.
18850 * Thus zero out the memory even though it is local
18851 * variable.
18852 */
18853 vos_mem_zero(&hddGtkOffloadReqParams,
18854 sizeof(hddGtkOffloadReqParams));
18855
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018856 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018857 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018858}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018859
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018860int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18861 struct cfg80211_gtk_rekey_data *data)
18862{
18863 int ret;
18864
18865 vos_ssr_protect(__func__);
18866 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18867 vos_ssr_unprotect(__func__);
18868
18869 return ret;
18870}
18871#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018872/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018873 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018874 * This function is used to set access control policy
18875 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018876static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18877 struct net_device *dev,
18878 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018879{
18880 int i;
18881 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18882 hdd_hostapd_state_t *pHostapdState;
18883 tsap_Config_t *pConfig;
18884 v_CONTEXT_t pVosContext = NULL;
18885 hdd_context_t *pHddCtx;
18886 int status;
18887
18888 ENTER();
18889
18890 if (NULL == pAdapter)
18891 {
18892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18893 "%s: HDD adapter is Null", __func__);
18894 return -ENODEV;
18895 }
18896
18897 if (NULL == params)
18898 {
18899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18900 "%s: params is Null", __func__);
18901 return -EINVAL;
18902 }
18903
18904 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18905 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018906 if (0 != status)
18907 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018908 return status;
18909 }
18910
18911 pVosContext = pHddCtx->pvosContext;
18912 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18913
18914 if (NULL == pHostapdState)
18915 {
18916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18917 "%s: pHostapdState is Null", __func__);
18918 return -EINVAL;
18919 }
18920
18921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18922 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018923 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18924 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18925 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018926
18927 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18928 {
18929 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18930
18931 /* default value */
18932 pConfig->num_accept_mac = 0;
18933 pConfig->num_deny_mac = 0;
18934
18935 /**
18936 * access control policy
18937 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18938 * listed in hostapd.deny file.
18939 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18940 * listed in hostapd.accept file.
18941 */
18942 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18943 {
18944 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18945 }
18946 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18947 {
18948 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18949 }
18950 else
18951 {
18952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18953 "%s:Acl Policy : %d is not supported",
18954 __func__, params->acl_policy);
18955 return -ENOTSUPP;
18956 }
18957
18958 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18959 {
18960 pConfig->num_accept_mac = params->n_acl_entries;
18961 for (i = 0; i < params->n_acl_entries; i++)
18962 {
18963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18964 "** Add ACL MAC entry %i in WhiletList :"
18965 MAC_ADDRESS_STR, i,
18966 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18967
18968 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18969 sizeof(qcmacaddr));
18970 }
18971 }
18972 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18973 {
18974 pConfig->num_deny_mac = params->n_acl_entries;
18975 for (i = 0; i < params->n_acl_entries; i++)
18976 {
18977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18978 "** Add ACL MAC entry %i in BlackList :"
18979 MAC_ADDRESS_STR, i,
18980 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18981
18982 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18983 sizeof(qcmacaddr));
18984 }
18985 }
18986
18987 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18988 {
18989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18990 "%s: SAP Set Mac Acl fail", __func__);
18991 return -EINVAL;
18992 }
18993 }
18994 else
18995 {
18996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018997 "%s: Invalid device_mode = %s (%d)",
18998 __func__, hdd_device_modetoString(pAdapter->device_mode),
18999 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019000 return -EINVAL;
19001 }
19002
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019003 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019004 return 0;
19005}
19006
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019007static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
19008 struct net_device *dev,
19009 const struct cfg80211_acl_data *params)
19010{
19011 int ret;
19012 vos_ssr_protect(__func__);
19013 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
19014 vos_ssr_unprotect(__func__);
19015
19016 return ret;
19017}
19018
Leo Chang9056f462013-08-01 19:21:11 -070019019#ifdef WLAN_NL80211_TESTMODE
19020#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070019021void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070019022(
19023 void *pAdapter,
19024 void *indCont
19025)
19026{
Leo Changd9df8aa2013-09-26 13:32:26 -070019027 tSirLPHBInd *lphbInd;
19028 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053019029 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070019030
19031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019032 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070019033
c_hpothu73f35e62014-04-18 13:40:08 +053019034 if (pAdapter == NULL)
19035 {
19036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19037 "%s: pAdapter is NULL\n",__func__);
19038 return;
19039 }
19040
Leo Chang9056f462013-08-01 19:21:11 -070019041 if (NULL == indCont)
19042 {
19043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070019044 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070019045 return;
19046 }
19047
c_hpothu73f35e62014-04-18 13:40:08 +053019048 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070019049 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070019050 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053019051 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070019052 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070019053 GFP_ATOMIC);
19054 if (!skb)
19055 {
19056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19057 "LPHB timeout, NL buffer alloc fail");
19058 return;
19059 }
19060
Leo Changac3ba772013-10-07 09:47:04 -070019061 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070019062 {
19063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19064 "WLAN_HDD_TM_ATTR_CMD put fail");
19065 goto nla_put_failure;
19066 }
Leo Changac3ba772013-10-07 09:47:04 -070019067 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070019068 {
19069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19070 "WLAN_HDD_TM_ATTR_TYPE put fail");
19071 goto nla_put_failure;
19072 }
Leo Changac3ba772013-10-07 09:47:04 -070019073 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070019074 sizeof(tSirLPHBInd), lphbInd))
19075 {
19076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19077 "WLAN_HDD_TM_ATTR_DATA put fail");
19078 goto nla_put_failure;
19079 }
Leo Chang9056f462013-08-01 19:21:11 -070019080 cfg80211_testmode_event(skb, GFP_ATOMIC);
19081 return;
19082
19083nla_put_failure:
19084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19085 "NLA Put fail");
19086 kfree_skb(skb);
19087
19088 return;
19089}
19090#endif /* FEATURE_WLAN_LPHB */
19091
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019092static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070019093{
19094 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
19095 int err = 0;
19096#ifdef FEATURE_WLAN_LPHB
19097 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070019098 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019099
19100 ENTER();
19101
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019102 err = wlan_hdd_validate_context(pHddCtx);
19103 if (0 != err)
19104 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019105 return err;
19106 }
Leo Chang9056f462013-08-01 19:21:11 -070019107#endif /* FEATURE_WLAN_LPHB */
19108
19109 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
19110 if (err)
19111 {
19112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19113 "%s Testmode INV ATTR", __func__);
19114 return err;
19115 }
19116
19117 if (!tb[WLAN_HDD_TM_ATTR_CMD])
19118 {
19119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19120 "%s Testmode INV CMD", __func__);
19121 return -EINVAL;
19122 }
19123
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019124 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19125 TRACE_CODE_HDD_CFG80211_TESTMODE,
19126 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070019127 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
19128 {
19129#ifdef FEATURE_WLAN_LPHB
19130 /* Low Power Heartbeat configuration request */
19131 case WLAN_HDD_TM_CMD_WLAN_HB:
19132 {
19133 int buf_len;
19134 void *buf;
19135 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080019136 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070019137
19138 if (!tb[WLAN_HDD_TM_ATTR_DATA])
19139 {
19140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19141 "%s Testmode INV DATA", __func__);
19142 return -EINVAL;
19143 }
19144
19145 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
19146 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080019147
19148 hb_params_temp =(tSirLPHBReq *)buf;
19149 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
19150 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
19151 return -EINVAL;
19152
Leo Chang9056f462013-08-01 19:21:11 -070019153 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
19154 if (NULL == hb_params)
19155 {
19156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19157 "%s Request Buffer Alloc Fail", __func__);
19158 return -EINVAL;
19159 }
19160
19161 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070019162 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
19163 hb_params,
19164 wlan_hdd_cfg80211_lphb_ind_handler);
19165 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070019166 {
Leo Changd9df8aa2013-09-26 13:32:26 -070019167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19168 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070019169 vos_mem_free(hb_params);
19170 }
Leo Chang9056f462013-08-01 19:21:11 -070019171 return 0;
19172 }
19173#endif /* FEATURE_WLAN_LPHB */
19174 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19176 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070019177 return -EOPNOTSUPP;
19178 }
19179
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019180 EXIT();
19181 return err;
Leo Chang9056f462013-08-01 19:21:11 -070019182}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019183
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053019184static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
19185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
19186 struct wireless_dev *wdev,
19187#endif
19188 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019189{
19190 int ret;
19191
19192 vos_ssr_protect(__func__);
19193 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
19194 vos_ssr_unprotect(__func__);
19195
19196 return ret;
19197}
Leo Chang9056f462013-08-01 19:21:11 -070019198#endif /* CONFIG_NL80211_TESTMODE */
19199
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019200static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019201 struct net_device *dev,
19202 int idx, struct survey_info *survey)
19203{
19204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19205 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053019206 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019207 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053019208 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019209 v_S7_t snr,rssi;
19210 int status, i, j, filled = 0;
19211
19212 ENTER();
19213
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019214 if (NULL == pAdapter)
19215 {
19216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19217 "%s: HDD adapter is Null", __func__);
19218 return -ENODEV;
19219 }
19220
19221 if (NULL == wiphy)
19222 {
19223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
19224 "%s: wiphy is Null", __func__);
19225 return -ENODEV;
19226 }
19227
19228 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19229 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019230 if (0 != status)
19231 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019232 return status;
19233 }
19234
Mihir Sheted9072e02013-08-21 17:02:29 +053019235 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19236
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019237 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053019238 0 != pAdapter->survey_idx ||
19239 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019240 {
19241 /* The survey dump ops when implemented completely is expected to
19242 * return a survey of all channels and the ops is called by the
19243 * kernel with incremental values of the argument 'idx' till it
19244 * returns -ENONET. But we can only support the survey for the
19245 * operating channel for now. survey_idx is used to track
19246 * that the ops is called only once and then return -ENONET for
19247 * the next iteration
19248 */
19249 pAdapter->survey_idx = 0;
19250 return -ENONET;
19251 }
19252
Mukul Sharma9d5233b2015-06-11 20:28:20 +053019253 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
19254 {
19255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19256 "%s: Roaming in progress, hence return ", __func__);
19257 return -ENONET;
19258 }
19259
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019260 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19261
19262 wlan_hdd_get_snr(pAdapter, &snr);
19263 wlan_hdd_get_rssi(pAdapter, &rssi);
19264
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019265 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19266 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
19267 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019268 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
19269 hdd_wlan_get_freq(channel, &freq);
19270
19271
19272 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
19273 {
19274 if (NULL == wiphy->bands[i])
19275 {
19276 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
19277 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
19278 continue;
19279 }
19280
19281 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
19282 {
19283 struct ieee80211_supported_band *band = wiphy->bands[i];
19284
19285 if (band->channels[j].center_freq == (v_U16_t)freq)
19286 {
19287 survey->channel = &band->channels[j];
19288 /* The Rx BDs contain SNR values in dB for the received frames
19289 * while the supplicant expects noise. So we calculate and
19290 * return the value of noise (dBm)
19291 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
19292 */
19293 survey->noise = rssi - snr;
19294 survey->filled = SURVEY_INFO_NOISE_DBM;
19295 filled = 1;
19296 }
19297 }
19298 }
19299
19300 if (filled)
19301 pAdapter->survey_idx = 1;
19302 else
19303 {
19304 pAdapter->survey_idx = 0;
19305 return -ENONET;
19306 }
19307
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019308 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019309 return 0;
19310}
19311
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019312static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
19313 struct net_device *dev,
19314 int idx, struct survey_info *survey)
19315{
19316 int ret;
19317
19318 vos_ssr_protect(__func__);
19319 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
19320 vos_ssr_unprotect(__func__);
19321
19322 return ret;
19323}
19324
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019325/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019326 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019327 * this is called when cfg80211 driver resume
19328 * driver updates latest sched_scan scan result(if any) to cfg80211 database
19329 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019330int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019331{
19332 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
19333 hdd_adapter_t *pAdapter;
19334 hdd_adapter_list_node_t *pAdapterNode, *pNext;
19335 VOS_STATUS status = VOS_STATUS_SUCCESS;
19336
19337 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019338
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019339 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019340 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019341 return 0;
19342 }
19343
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019344 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
19345 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019346 spin_lock(&pHddCtx->schedScan_lock);
19347 pHddCtx->isWiphySuspended = FALSE;
19348 if (TRUE != pHddCtx->isSchedScanUpdatePending)
19349 {
19350 spin_unlock(&pHddCtx->schedScan_lock);
19351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19352 "%s: Return resume is not due to PNO indication", __func__);
19353 return 0;
19354 }
19355 // Reset flag to avoid updatating cfg80211 data old results again
19356 pHddCtx->isSchedScanUpdatePending = FALSE;
19357 spin_unlock(&pHddCtx->schedScan_lock);
19358
19359 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
19360
19361 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
19362 {
19363 pAdapter = pAdapterNode->pAdapter;
19364 if ( (NULL != pAdapter) &&
19365 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
19366 {
19367 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019368 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19370 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019371 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019372 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019373 {
19374 /* Acquire wakelock to handle the case where APP's tries to
19375 * suspend immediately after updating the scan results. Whis
19376 * results in app's is in suspended state and not able to
19377 * process the connect request to AP
19378 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053019379 hdd_prevent_suspend_timeout(2000,
19380 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019381 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053019382 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019383
19384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19385 "%s : cfg80211 scan result database updated", __func__);
19386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019387 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019388 return 0;
19389
19390 }
19391 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19392 pAdapterNode = pNext;
19393 }
19394
19395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19396 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019397 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019398 return 0;
19399}
19400
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019401int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
19402{
19403 int ret;
19404
19405 vos_ssr_protect(__func__);
19406 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
19407 vos_ssr_unprotect(__func__);
19408
19409 return ret;
19410}
19411
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019412/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019413 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019414 * this is called when cfg80211 driver suspends
19415 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019416int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019417 struct cfg80211_wowlan *wow)
19418{
19419 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019420 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019421
19422 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019423
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019424 ret = wlan_hdd_validate_context(pHddCtx);
19425 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019426 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019427 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019428 }
19429
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019430
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019431 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19432 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
19433 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019434 pHddCtx->isWiphySuspended = TRUE;
19435
19436 EXIT();
19437
19438 return 0;
19439}
19440
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053019441int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
19442 struct cfg80211_wowlan *wow)
19443{
19444 int ret;
19445
19446 vos_ssr_protect(__func__);
19447 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
19448 vos_ssr_unprotect(__func__);
19449
19450 return ret;
19451}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019452
19453#ifdef FEATURE_OEM_DATA_SUPPORT
19454static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019455 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019456{
19457 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19458
19459 ENTER();
19460
19461 if (wlan_hdd_validate_context(pHddCtx)) {
19462 return;
19463 }
19464 if (!pMsg)
19465 {
19466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
19467 return;
19468 }
19469
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019470 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019471
19472 EXIT();
19473 return;
19474
19475}
19476
19477void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019478 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019479{
19480 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
19481
19482 ENTER();
19483
19484 if (wlan_hdd_validate_context(pHddCtx)) {
19485 return;
19486 }
19487
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019488 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019489
19490 switch(evType) {
19491 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053019492 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053019493 break;
19494 default:
19495 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
19496 break;
19497 }
19498 EXIT();
19499}
19500#endif
19501
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019502#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19503 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019504/**
19505 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
19506 * @wiphy: Pointer to wiphy
19507 * @wdev: Pointer to wireless device structure
19508 *
19509 * This function is used to abort an ongoing scan
19510 *
19511 * Return: None
19512 */
19513static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19514 struct wireless_dev *wdev)
19515{
19516 struct net_device *dev = wdev->netdev;
19517 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19518 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19519 int ret;
19520
19521 ENTER();
19522
19523 if (NULL == adapter) {
19524 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
19525 return;
19526 }
19527
19528 ret = wlan_hdd_validate_context(hdd_ctx);
19529 if (0 != ret)
19530 return;
19531
19532 wlan_hdd_scan_abort(adapter);
19533
19534 return;
19535}
19536
19537/**
19538 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
19539 * @wiphy: Pointer to wiphy
19540 * @wdev: Pointer to wireless device structure
19541 *
19542 * Return: None
19543 */
19544void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
19545 struct wireless_dev *wdev)
19546{
19547 vos_ssr_protect(__func__);
19548 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
19549 vos_ssr_unprotect(__func__);
19550
19551 return;
19552}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019553#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019554
Jeff Johnson295189b2012-06-20 16:38:30 -070019555/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019556static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070019557{
19558 .add_virtual_intf = wlan_hdd_add_virtual_intf,
19559 .del_virtual_intf = wlan_hdd_del_virtual_intf,
19560 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
19561 .change_station = wlan_hdd_change_station,
19562#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
19563 .add_beacon = wlan_hdd_cfg80211_add_beacon,
19564 .del_beacon = wlan_hdd_cfg80211_del_beacon,
19565 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019566#else
19567 .start_ap = wlan_hdd_cfg80211_start_ap,
19568 .change_beacon = wlan_hdd_cfg80211_change_beacon,
19569 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070019570#endif
19571 .change_bss = wlan_hdd_cfg80211_change_bss,
19572 .add_key = wlan_hdd_cfg80211_add_key,
19573 .get_key = wlan_hdd_cfg80211_get_key,
19574 .del_key = wlan_hdd_cfg80211_del_key,
19575 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019576#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070019577 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080019578#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019579 .scan = wlan_hdd_cfg80211_scan,
19580 .connect = wlan_hdd_cfg80211_connect,
19581 .disconnect = wlan_hdd_cfg80211_disconnect,
19582 .join_ibss = wlan_hdd_cfg80211_join_ibss,
19583 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19584 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19585 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19586 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019587 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19588 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019589 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019590#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19591 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19592 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19593 .set_txq_params = wlan_hdd_set_txq_params,
19594#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019595 .get_station = wlan_hdd_cfg80211_get_station,
19596 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19597 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019598 .add_station = wlan_hdd_cfg80211_add_station,
19599#ifdef FEATURE_WLAN_LFR
19600 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19601 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19602 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19603#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019604#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19605 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19606#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019607#ifdef FEATURE_WLAN_TDLS
19608 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19609 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19610#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019611#ifdef WLAN_FEATURE_GTK_OFFLOAD
19612 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19613#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019614#ifdef FEATURE_WLAN_SCAN_PNO
19615 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19616 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19617#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019618 .resume = wlan_hdd_cfg80211_resume_wlan,
19619 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019620 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019621#ifdef WLAN_NL80211_TESTMODE
19622 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19623#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019624 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
19626 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053019627 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053019628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019629};
19630