blob: 8ee9b31c7b4f4434ac2d51dc20e128d17006ceaa [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#ifdef FEATURE_WLAN_TDLS
94#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080097#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053098#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070099#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100
101#define g_mode_rates_size (12)
102#define a_mode_rates_size (8)
103#define FREQ_BASE_80211G (2407)
104#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700105#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530106#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800108 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110#define HDD2GHZCHAN(freq, chan, flag) { \
111 .band = IEEE80211_BAND_2GHZ, \
112 .center_freq = (freq), \
113 .hw_value = (chan),\
114 .flags = (flag), \
115 .max_antenna_gain = 0 ,\
116 .max_power = 30, \
117}
118
119#define HDD5GHZCHAN(freq, chan, flag) { \
120 .band = IEEE80211_BAND_5GHZ, \
121 .center_freq = (freq), \
122 .hw_value = (chan),\
123 .flags = (flag), \
124 .max_antenna_gain = 0 ,\
125 .max_power = 30, \
126}
127
128#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
129{\
130 .bitrate = rate, \
131 .hw_value = rate_id, \
132 .flags = flag, \
133}
134
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530135#ifdef WLAN_FEATURE_VOWIFI_11R
136#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
137#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
138#endif
139
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530141#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142
Sunil Duttc69bccb2014-05-26 21:30:20 +0530143#ifdef WLAN_FEATURE_LINK_LAYER_STATS
144/*
145 * Used to allocate the size of 4096 for the link layer stats.
146 * The size of 4096 is considered assuming that all data per
147 * respective event fit with in the limit.Please take a call
148 * on the limit based on the data requirements on link layer
149 * statistics.
150 */
151#define LL_STATS_EVENT_BUF_SIZE 4096
152#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530153#ifdef WLAN_FEATURE_EXTSCAN
154/*
155 * Used to allocate the size of 4096 for the EXTScan NL data.
156 * The size of 4096 is considered assuming that all data per
157 * respective event fit with in the limit.Please take a call
158 * on the limit based on the data requirements.
159 */
160
161#define EXTSCAN_EVENT_BUF_SIZE 4096
162#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
163#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530164
Atul Mittal115287b2014-07-08 13:26:33 +0530165/*EXT TDLS*/
166/*
167 * Used to allocate the size of 4096 for the TDLS.
168 * The size of 4096 is considered assuming that all data per
169 * respective event fit with in the limit.Please take a call
170 * on the limit based on the data requirements on link layer
171 * statistics.
172 */
173#define EXTTDLS_EVENT_BUF_SIZE 4096
174
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530175static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700176{
177 WLAN_CIPHER_SUITE_WEP40,
178 WLAN_CIPHER_SUITE_WEP104,
179 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800180#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700181#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
182 WLAN_CIPHER_SUITE_KRK,
183 WLAN_CIPHER_SUITE_CCMP,
184#else
185 WLAN_CIPHER_SUITE_CCMP,
186#endif
187#ifdef FEATURE_WLAN_WAPI
188 WLAN_CIPHER_SUITE_SMS4,
189#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700190#ifdef WLAN_FEATURE_11W
191 WLAN_CIPHER_SUITE_AES_CMAC,
192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700193};
194
195static inline int is_broadcast_ether_addr(const u8 *addr)
196{
197 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
198 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
199}
200
201static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530202{
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 HDD2GHZCHAN(2412, 1, 0) ,
204 HDD2GHZCHAN(2417, 2, 0) ,
205 HDD2GHZCHAN(2422, 3, 0) ,
206 HDD2GHZCHAN(2427, 4, 0) ,
207 HDD2GHZCHAN(2432, 5, 0) ,
208 HDD2GHZCHAN(2437, 6, 0) ,
209 HDD2GHZCHAN(2442, 7, 0) ,
210 HDD2GHZCHAN(2447, 8, 0) ,
211 HDD2GHZCHAN(2452, 9, 0) ,
212 HDD2GHZCHAN(2457, 10, 0) ,
213 HDD2GHZCHAN(2462, 11, 0) ,
214 HDD2GHZCHAN(2467, 12, 0) ,
215 HDD2GHZCHAN(2472, 13, 0) ,
216 HDD2GHZCHAN(2484, 14, 0) ,
217};
218
Jeff Johnson295189b2012-06-20 16:38:30 -0700219static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
220{
221 HDD2GHZCHAN(2412, 1, 0) ,
222 HDD2GHZCHAN(2437, 6, 0) ,
223 HDD2GHZCHAN(2462, 11, 0) ,
224};
Jeff Johnson295189b2012-06-20 16:38:30 -0700225
226static struct ieee80211_channel hdd_channels_5_GHZ[] =
227{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700228 HDD5GHZCHAN(4920, 240, 0) ,
229 HDD5GHZCHAN(4940, 244, 0) ,
230 HDD5GHZCHAN(4960, 248, 0) ,
231 HDD5GHZCHAN(4980, 252, 0) ,
232 HDD5GHZCHAN(5040, 208, 0) ,
233 HDD5GHZCHAN(5060, 212, 0) ,
234 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700235 HDD5GHZCHAN(5180, 36, 0) ,
236 HDD5GHZCHAN(5200, 40, 0) ,
237 HDD5GHZCHAN(5220, 44, 0) ,
238 HDD5GHZCHAN(5240, 48, 0) ,
239 HDD5GHZCHAN(5260, 52, 0) ,
240 HDD5GHZCHAN(5280, 56, 0) ,
241 HDD5GHZCHAN(5300, 60, 0) ,
242 HDD5GHZCHAN(5320, 64, 0) ,
243 HDD5GHZCHAN(5500,100, 0) ,
244 HDD5GHZCHAN(5520,104, 0) ,
245 HDD5GHZCHAN(5540,108, 0) ,
246 HDD5GHZCHAN(5560,112, 0) ,
247 HDD5GHZCHAN(5580,116, 0) ,
248 HDD5GHZCHAN(5600,120, 0) ,
249 HDD5GHZCHAN(5620,124, 0) ,
250 HDD5GHZCHAN(5640,128, 0) ,
251 HDD5GHZCHAN(5660,132, 0) ,
252 HDD5GHZCHAN(5680,136, 0) ,
253 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800254#ifdef FEATURE_WLAN_CH144
255 HDD5GHZCHAN(5720,144, 0) ,
256#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 HDD5GHZCHAN(5745,149, 0) ,
258 HDD5GHZCHAN(5765,153, 0) ,
259 HDD5GHZCHAN(5785,157, 0) ,
260 HDD5GHZCHAN(5805,161, 0) ,
261 HDD5GHZCHAN(5825,165, 0) ,
262};
263
264static struct ieee80211_rate g_mode_rates[] =
265{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530266 HDD_G_MODE_RATETAB(10, 0x1, 0),
267 HDD_G_MODE_RATETAB(20, 0x2, 0),
268 HDD_G_MODE_RATETAB(55, 0x4, 0),
269 HDD_G_MODE_RATETAB(110, 0x8, 0),
270 HDD_G_MODE_RATETAB(60, 0x10, 0),
271 HDD_G_MODE_RATETAB(90, 0x20, 0),
272 HDD_G_MODE_RATETAB(120, 0x40, 0),
273 HDD_G_MODE_RATETAB(180, 0x80, 0),
274 HDD_G_MODE_RATETAB(240, 0x100, 0),
275 HDD_G_MODE_RATETAB(360, 0x200, 0),
276 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530278};
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
280static struct ieee80211_rate a_mode_rates[] =
281{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282 HDD_G_MODE_RATETAB(60, 0x10, 0),
283 HDD_G_MODE_RATETAB(90, 0x20, 0),
284 HDD_G_MODE_RATETAB(120, 0x40, 0),
285 HDD_G_MODE_RATETAB(180, 0x80, 0),
286 HDD_G_MODE_RATETAB(240, 0x100, 0),
287 HDD_G_MODE_RATETAB(360, 0x200, 0),
288 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700289 HDD_G_MODE_RATETAB(540, 0x800, 0),
290};
291
292static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
293{
294 .channels = hdd_channels_2_4_GHZ,
295 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
296 .band = IEEE80211_BAND_2GHZ,
297 .bitrates = g_mode_rates,
298 .n_bitrates = g_mode_rates_size,
299 .ht_cap.ht_supported = 1,
300 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
301 | IEEE80211_HT_CAP_GRN_FLD
302 | IEEE80211_HT_CAP_DSSSCCK40
303 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
304 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
305 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
306 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
307 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
308 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
309};
310
Jeff Johnson295189b2012-06-20 16:38:30 -0700311static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
312{
313 .channels = hdd_social_channels_2_4_GHZ,
314 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
315 .band = IEEE80211_BAND_2GHZ,
316 .bitrates = g_mode_rates,
317 .n_bitrates = g_mode_rates_size,
318 .ht_cap.ht_supported = 1,
319 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
320 | IEEE80211_HT_CAP_GRN_FLD
321 | IEEE80211_HT_CAP_DSSSCCK40
322 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
323 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
324 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
325 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
326 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
327 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
328};
Jeff Johnson295189b2012-06-20 16:38:30 -0700329
330static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
331{
332 .channels = hdd_channels_5_GHZ,
333 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
334 .band = IEEE80211_BAND_5GHZ,
335 .bitrates = a_mode_rates,
336 .n_bitrates = a_mode_rates_size,
337 .ht_cap.ht_supported = 1,
338 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
339 | IEEE80211_HT_CAP_GRN_FLD
340 | IEEE80211_HT_CAP_DSSSCCK40
341 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
342 | IEEE80211_HT_CAP_SGI_40
343 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
344 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
345 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
346 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
347 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
348 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
349};
350
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530351/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 TX/RX direction for each kind of interface */
353static const struct ieee80211_txrx_stypes
354wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
355 [NL80211_IFTYPE_STATION] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ACTION) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ),
359 },
360 [NL80211_IFTYPE_AP] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700370 [NL80211_IFTYPE_ADHOC] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
373 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_PROBE_REQ) |
375 BIT(SIR_MAC_MGMT_DISASSOC) |
376 BIT(SIR_MAC_MGMT_AUTH) |
377 BIT(SIR_MAC_MGMT_DEAUTH) |
378 BIT(SIR_MAC_MGMT_ACTION),
379 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 [NL80211_IFTYPE_P2P_CLIENT] = {
381 .tx = 0xffff,
382 .rx = BIT(SIR_MAC_MGMT_ACTION) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ),
384 },
385 [NL80211_IFTYPE_P2P_GO] = {
386 /* This is also same as for SoftAP */
387 .tx = 0xffff,
388 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
389 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_PROBE_REQ) |
391 BIT(SIR_MAC_MGMT_DISASSOC) |
392 BIT(SIR_MAC_MGMT_AUTH) |
393 BIT(SIR_MAC_MGMT_DEAUTH) |
394 BIT(SIR_MAC_MGMT_ACTION),
395 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700396};
397
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399static const struct ieee80211_iface_limit
400wlan_hdd_iface_limit[] = {
401 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800402 /* max = 3 ; Our driver create two interfaces during driver init
403 * wlan0 and p2p0 interfaces. p2p0 is considered as station
404 * interface until a group is formed. In JB architecture, once the
405 * group is formed, interface type of p2p0 is changed to P2P GO or
406 * Client.
407 * When supplicant remove the group, it first issue a set interface
408 * cmd to change the mode back to Station. In JB this works fine as
409 * we advertize two station type interface during driver init.
410 * Some vendors create separate interface for P2P GO/Client,
411 * after group formation(Third one). But while group remove
412 * supplicant first tries to change the mode(3rd interface) to STATION
413 * But as we advertized only two sta type interfaces nl80211 was
414 * returning error for the third one which was leading to failure in
415 * delete interface. Ideally while removing the group, supplicant
416 * should not try to change the 3rd interface mode to Station type.
417 * Till we get a fix in wpa_supplicant, we advertize max STA
418 * interface type to 3
419 */
420 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .types = BIT(NL80211_IFTYPE_STATION),
422 },
423 {
424 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700425 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800426 },
427 {
428 .max = 1,
429 .types = BIT(NL80211_IFTYPE_P2P_GO) |
430 BIT(NL80211_IFTYPE_P2P_CLIENT),
431 },
432};
433
434/* By default, only single channel concurrency is allowed */
435static struct ieee80211_iface_combination
436wlan_hdd_iface_combination = {
437 .limits = wlan_hdd_iface_limit,
438 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800439 /*
440 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
441 * and p2p0 interfaces during driver init
442 * Some vendors create separate interface for P2P operations.
443 * wlan0: STA interface
444 * p2p0: P2P Device interface, action frames goes
445 * through this interface.
446 * p2p-xx: P2P interface, After GO negotiation this interface is
447 * created for p2p operations(GO/CLIENT interface).
448 */
449 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800450 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
451 .beacon_int_infra_match = false,
452};
453#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800454
Jeff Johnson295189b2012-06-20 16:38:30 -0700455static struct cfg80211_ops wlan_hdd_cfg80211_ops;
456
457/* Data rate 100KBPS based on IE Index */
458struct index_data_rate_type
459{
460 v_U8_t beacon_rate_index;
461 v_U16_t supported_rate[4];
462};
463
464/* 11B, 11G Rate table include Basic rate and Extended rate
465 The IDX field is the rate index
466 The HI field is the rate when RSSI is strong or being ignored
467 (in this case we report actual rate)
468 The MID field is the rate when RSSI is moderate
469 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
470 The LO field is the rate when RSSI is low
471 (in this case we don't report rates, actual current rate used)
472 */
473static const struct
474{
475 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700476 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700477} supported_data_rate[] =
478{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700479/* IDX HI HM LM LO (RSSI-based index */
480 {2, { 10, 10, 10, 0}},
481 {4, { 20, 20, 10, 0}},
482 {11, { 55, 20, 10, 0}},
483 {12, { 60, 55, 20, 0}},
484 {18, { 90, 55, 20, 0}},
485 {22, {110, 55, 20, 0}},
486 {24, {120, 90, 60, 0}},
487 {36, {180, 120, 60, 0}},
488 {44, {220, 180, 60, 0}},
489 {48, {240, 180, 90, 0}},
490 {66, {330, 180, 90, 0}},
491 {72, {360, 240, 90, 0}},
492 {96, {480, 240, 120, 0}},
493 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700494};
495
496/* MCS Based rate table */
497static struct index_data_rate_type supported_mcs_rate[] =
498{
499/* MCS L20 L40 S20 S40 */
500 {0, {65, 135, 72, 150}},
501 {1, {130, 270, 144, 300}},
502 {2, {195, 405, 217, 450}},
503 {3, {260, 540, 289, 600}},
504 {4, {390, 810, 433, 900}},
505 {5, {520, 1080, 578, 1200}},
506 {6, {585, 1215, 650, 1350}},
507 {7, {650, 1350, 722, 1500}}
508};
509
Leo Chang6f8870f2013-03-26 18:11:36 -0700510#ifdef WLAN_FEATURE_11AC
511
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530512#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700513
514struct index_vht_data_rate_type
515{
516 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530517 v_U16_t supported_VHT80_rate[2];
518 v_U16_t supported_VHT40_rate[2];
519 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700520};
521
522typedef enum
523{
524 DATA_RATE_11AC_MAX_MCS_7,
525 DATA_RATE_11AC_MAX_MCS_8,
526 DATA_RATE_11AC_MAX_MCS_9,
527 DATA_RATE_11AC_MAX_MCS_NA
528} eDataRate11ACMaxMcs;
529
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530530/* SSID broadcast type */
531typedef enum eSSIDBcastType
532{
533 eBCAST_UNKNOWN = 0,
534 eBCAST_NORMAL = 1,
535 eBCAST_HIDDEN = 2,
536} tSSIDBcastType;
537
Leo Chang6f8870f2013-03-26 18:11:36 -0700538/* MCS Based VHT rate table */
539static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
540{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530541/* MCS L80 S80 L40 S40 L20 S40*/
542 {0, {293, 325}, {135, 150}, {65, 72}},
543 {1, {585, 650}, {270, 300}, {130, 144}},
544 {2, {878, 975}, {405, 450}, {195, 217}},
545 {3, {1170, 1300}, {540, 600}, {260, 289}},
546 {4, {1755, 1950}, {810, 900}, {390, 433}},
547 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
548 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
549 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
550 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
551 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700552};
553#endif /* WLAN_FEATURE_11AC */
554
c_hpothu79aab322014-07-14 21:11:01 +0530555/*array index points to MCS and array value points respective rssi*/
556static int rssiMcsTbl[][10] =
557{
558/*MCS 0 1 2 3 4 5 6 7 8 9*/
559 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
560 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
561 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
562};
563
Jeff Johnson295189b2012-06-20 16:38:30 -0700564extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530565#ifdef FEATURE_WLAN_SCAN_PNO
566static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
567#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700568
Leo Chang9056f462013-08-01 19:21:11 -0700569#ifdef WLAN_NL80211_TESTMODE
570enum wlan_hdd_tm_attr
571{
572 WLAN_HDD_TM_ATTR_INVALID = 0,
573 WLAN_HDD_TM_ATTR_CMD = 1,
574 WLAN_HDD_TM_ATTR_DATA = 2,
575 WLAN_HDD_TM_ATTR_TYPE = 3,
576 /* keep last */
577 WLAN_HDD_TM_ATTR_AFTER_LAST,
578 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
579};
580
581enum wlan_hdd_tm_cmd
582{
583 WLAN_HDD_TM_CMD_WLAN_HB = 1,
584};
585
586#define WLAN_HDD_TM_DATA_MAX_LEN 5000
587
588static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
589{
590 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
591 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
592 .len = WLAN_HDD_TM_DATA_MAX_LEN },
593};
594#endif /* WLAN_NL80211_TESTMODE */
595
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800596#ifdef FEATURE_WLAN_CH_AVOID
597/*
598 * FUNCTION: wlan_hdd_send_avoid_freq_event
599 * This is called when wlan driver needs to send vendor specific
600 * avoid frequency range event to userspace
601 */
602int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
603 tHddAvoidFreqList *pAvoidFreqList)
604{
605 struct sk_buff *vendor_event;
606
607 ENTER();
608
609 if (!pHddCtx)
610 {
611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
612 "%s: HDD context is null", __func__);
613 return -1;
614 }
615
616 if (!pAvoidFreqList)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: pAvoidFreqList is null", __func__);
620 return -1;
621 }
622
623 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
624 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530625 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800626 GFP_KERNEL);
627 if (!vendor_event)
628 {
629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
630 "%s: cfg80211_vendor_event_alloc failed", __func__);
631 return -1;
632 }
633
634 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
635 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
636
637 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
638
639 EXIT();
640 return 0;
641}
642#endif /* FEATURE_WLAN_CH_AVOID */
643
Srinivas Dasari030bad32015-02-18 23:23:54 +0530644/*
645 * FUNCTION: __wlan_hdd_cfg80211_nan_request
646 * This is called when wlan driver needs to send vendor specific
647 * nan request event.
648 */
649static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
650 struct wireless_dev *wdev,
651 const void *data, int data_len)
652{
653 tNanRequestReq nan_req;
654 VOS_STATUS status;
655 int ret_val = -1;
656 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
657
658 if (0 == data_len)
659 {
660 hddLog(VOS_TRACE_LEVEL_ERROR,
661 FL("NAN - Invalid Request, length = 0"));
662 return ret_val;
663 }
664
665 if (NULL == data)
666 {
667 hddLog(VOS_TRACE_LEVEL_ERROR,
668 FL("NAN - Invalid Request, data is NULL"));
669 return ret_val;
670 }
671
672 status = wlan_hdd_validate_context(pHddCtx);
673 if (0 != status)
674 {
675 hddLog(VOS_TRACE_LEVEL_ERROR,
676 FL("HDD context is not valid"));
677 return -EINVAL;
678 }
679
680 hddLog(LOG1, FL("Received NAN command"));
681 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
682 (tANI_U8 *)data, data_len);
683
684 /* check the NAN Capability */
685 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
686 {
687 hddLog(VOS_TRACE_LEVEL_ERROR,
688 FL("NAN is not supported by Firmware"));
689 return -EINVAL;
690 }
691
692 nan_req.request_data_len = data_len;
693 nan_req.request_data = data;
694
695 status = sme_NanRequest(&nan_req);
696 if (VOS_STATUS_SUCCESS == status)
697 {
698 ret_val = 0;
699 }
700 return ret_val;
701}
702
703/*
704 * FUNCTION: wlan_hdd_cfg80211_nan_request
705 * Wrapper to protect the nan vendor command from ssr
706 */
707static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
708 struct wireless_dev *wdev,
709 const void *data, int data_len)
710{
711 int ret;
712
713 vos_ssr_protect(__func__);
714 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
715 vos_ssr_unprotect(__func__);
716
717 return ret;
718}
719
720/*
721 * FUNCTION: wlan_hdd_cfg80211_nan_callback
722 * This is a callback function and it gets called
723 * when we need to report nan response event to
724 * upper layers.
725 */
726static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
727{
728 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
729 struct sk_buff *vendor_event;
730 int status;
731 tSirNanEvent *data;
732
733 ENTER();
734 if (NULL == msg)
735 {
736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 FL(" msg received here is null"));
738 return;
739 }
740 data = msg;
741
742 status = wlan_hdd_validate_context(pHddCtx);
743
744 if (0 != status)
745 {
746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
747 FL("HDD context is not valid"));
748 return;
749 }
750
751 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
752 data->event_data_len +
753 NLMSG_HDRLEN,
754 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
755 GFP_KERNEL);
756
757 if (!vendor_event)
758 {
759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
760 FL("cfg80211_vendor_event_alloc failed"));
761 return;
762 }
763 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
764 data->event_data_len, data->event_data))
765 {
766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
767 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
768 kfree_skb(vendor_event);
769 return;
770 }
771 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
772 EXIT();
773}
774
775/*
776 * FUNCTION: wlan_hdd_cfg80211_nan_init
777 * This function is called to register the callback to sme layer
778 */
779inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
780{
781 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
782}
783
784
Sunil Duttc69bccb2014-05-26 21:30:20 +0530785#ifdef WLAN_FEATURE_LINK_LAYER_STATS
786
787static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
788 struct sk_buff *vendor_event)
789{
790 if (nla_put_u8(vendor_event,
791 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
792 stats->rate.preamble) ||
793 nla_put_u8(vendor_event,
794 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
795 stats->rate.nss) ||
796 nla_put_u8(vendor_event,
797 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
798 stats->rate.bw) ||
799 nla_put_u8(vendor_event,
800 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
801 stats->rate.rateMcsIdx) ||
802 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
803 stats->rate.bitrate ) ||
804 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
805 stats->txMpdu ) ||
806 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
807 stats->rxMpdu ) ||
808 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
809 stats->mpduLost ) ||
810 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
811 stats->retries) ||
812 nla_put_u32(vendor_event,
813 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
814 stats->retriesShort ) ||
815 nla_put_u32(vendor_event,
816 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
817 stats->retriesLong))
818 {
819 hddLog(VOS_TRACE_LEVEL_ERROR,
820 FL("QCA_WLAN_VENDOR_ATTR put fail"));
821 return FALSE;
822 }
823 return TRUE;
824}
825
826static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
827 struct sk_buff *vendor_event)
828{
829 u32 i = 0;
830 struct nlattr *rateInfo;
831 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
832 stats->type) ||
833 nla_put(vendor_event,
834 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
835 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
836 nla_put_u32(vendor_event,
837 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
838 stats->capabilities) ||
839 nla_put_u32(vendor_event,
840 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
841 stats->numRate))
842 {
843 hddLog(VOS_TRACE_LEVEL_ERROR,
844 FL("QCA_WLAN_VENDOR_ATTR put fail"));
845 goto error;
846 }
847
848 rateInfo = nla_nest_start(vendor_event,
849 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530850 if(!rateInfo)
851 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530852 for (i = 0; i < stats->numRate; i++)
853 {
854 struct nlattr *rates;
855 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
856 stats->rateStats +
857 (i * sizeof(tSirWifiRateStat)));
858 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530859 if(!rates)
860 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530861
862 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
863 {
864 hddLog(VOS_TRACE_LEVEL_ERROR,
865 FL("QCA_WLAN_VENDOR_ATTR put fail"));
866 return FALSE;
867 }
868 nla_nest_end(vendor_event, rates);
869 }
870 nla_nest_end(vendor_event, rateInfo);
871
872 return TRUE;
873error:
874 return FALSE;
875}
876
877static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
878 struct sk_buff *vendor_event)
879{
880 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
881 stats->ac ) ||
882 nla_put_u32(vendor_event,
883 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
884 stats->txMpdu ) ||
885 nla_put_u32(vendor_event,
886 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
887 stats->rxMpdu ) ||
888 nla_put_u32(vendor_event,
889 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
890 stats->txMcast ) ||
891 nla_put_u32(vendor_event,
892 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
893 stats->rxMcast ) ||
894 nla_put_u32(vendor_event,
895 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
896 stats->rxAmpdu ) ||
897 nla_put_u32(vendor_event,
898 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
899 stats->txAmpdu ) ||
900 nla_put_u32(vendor_event,
901 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
902 stats->mpduLost )||
903 nla_put_u32(vendor_event,
904 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
905 stats->retries ) ||
906 nla_put_u32(vendor_event,
907 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
908 stats->retriesShort ) ||
909 nla_put_u32(vendor_event,
910 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
911 stats->retriesLong ) ||
912 nla_put_u32(vendor_event,
913 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
914 stats->contentionTimeMin ) ||
915 nla_put_u32(vendor_event,
916 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
917 stats->contentionTimeMax ) ||
918 nla_put_u32(vendor_event,
919 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
920 stats->contentionTimeAvg ) ||
921 nla_put_u32(vendor_event,
922 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
923 stats->contentionNumSamples ))
924 {
925 hddLog(VOS_TRACE_LEVEL_ERROR,
926 FL("QCA_WLAN_VENDOR_ATTR put fail") );
927 return FALSE;
928 }
929 return TRUE;
930}
931
932static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
933 struct sk_buff *vendor_event)
934{
Dino Myclec8f3f332014-07-21 16:48:27 +0530935 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530936 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
937 nla_put(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
939 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
942 stats->state ) ||
943 nla_put_u32(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
945 stats->roaming ) ||
946 nla_put_u32(vendor_event,
947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
948 stats->capabilities ) ||
949 nla_put(vendor_event,
950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
951 strlen(stats->ssid), stats->ssid) ||
952 nla_put(vendor_event,
953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
954 WNI_CFG_BSSID_LEN, stats->bssid) ||
955 nla_put(vendor_event,
956 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
957 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
958 nla_put(vendor_event,
959 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
960 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
961 )
962 {
963 hddLog(VOS_TRACE_LEVEL_ERROR,
964 FL("QCA_WLAN_VENDOR_ATTR put fail") );
965 return FALSE;
966 }
967 return TRUE;
968}
969
Dino Mycle3b9536d2014-07-09 22:05:24 +0530970static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
971 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530972 struct sk_buff *vendor_event)
973{
974 int i = 0;
975 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530976 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
977 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530978 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530979
Sunil Duttc69bccb2014-05-26 21:30:20 +0530980 if (FALSE == put_wifi_interface_info(
981 &pWifiIfaceStat->info,
982 vendor_event))
983 {
984 hddLog(VOS_TRACE_LEVEL_ERROR,
985 FL("QCA_WLAN_VENDOR_ATTR put fail") );
986 return FALSE;
987
988 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530989 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
990 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
991 if (NULL == pWifiIfaceStatTL)
992 {
993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
994 return FALSE;
995 }
996
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530997 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
999 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1000 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1001
1002 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1003 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1004 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1005 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301006
1007 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1008 {
1009 if (VOS_STATUS_SUCCESS ==
1010 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1011 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1012 {
1013 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1014 * obtained from TL structure
1015 */
1016
1017 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1018 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301019 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1020
Srinivas Dasari98947432014-11-07 19:41:24 +05301021 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1022 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1023 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1024 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1025 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1026 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1027 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1028 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301029
Srinivas Dasari98947432014-11-07 19:41:24 +05301030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1036 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1037 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301038
Srinivas Dasari98947432014-11-07 19:41:24 +05301039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1045 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1046 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301047 }
1048 else
1049 {
1050 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1051 }
1052
Dino Mycle3b9536d2014-07-09 22:05:24 +05301053 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1055 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1056 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1057 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1058 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1059 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1060 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1061 }
1062 else
1063 {
1064 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1065 }
1066
1067
Sunil Duttc69bccb2014-05-26 21:30:20 +05301068
1069 if (nla_put_u32(vendor_event,
1070 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1071 pWifiIfaceStat->beaconRx) ||
1072 nla_put_u32(vendor_event,
1073 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1074 pWifiIfaceStat->mgmtRx) ||
1075 nla_put_u32(vendor_event,
1076 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1077 pWifiIfaceStat->mgmtActionRx) ||
1078 nla_put_u32(vendor_event,
1079 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1080 pWifiIfaceStat->mgmtActionTx) ||
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_MGMT,
1083 pWifiIfaceStat->rssiMgmt) ||
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_DATA,
1086 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301087 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301088 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1089 pWifiIfaceStat->rssiAck))
1090 {
1091 hddLog(VOS_TRACE_LEVEL_ERROR,
1092 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301093 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301094 return FALSE;
1095 }
1096
1097 wmmInfo = nla_nest_start(vendor_event,
1098 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301099 if(!wmmInfo)
1100 {
1101 vos_mem_free(pWifiIfaceStatTL);
1102 return FALSE;
1103 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301104 for (i = 0; i < WIFI_AC_MAX; i++)
1105 {
1106 struct nlattr *wmmStats;
1107 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301108 if(!wmmStats)
1109 {
1110 vos_mem_free(pWifiIfaceStatTL);
1111 return FALSE;
1112 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301113 if (FALSE == put_wifi_wmm_ac_stat(
1114 &pWifiIfaceStat->AccessclassStats[i],
1115 vendor_event))
1116 {
1117 hddLog(VOS_TRACE_LEVEL_ERROR,
1118 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301119 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301120 return FALSE;
1121 }
1122
1123 nla_nest_end(vendor_event, wmmStats);
1124 }
1125 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301126 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301127 return TRUE;
1128}
1129
1130static tSirWifiInterfaceMode
1131 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1132{
1133 switch (deviceMode)
1134 {
1135 case WLAN_HDD_INFRA_STATION:
1136 return WIFI_INTERFACE_STA;
1137 case WLAN_HDD_SOFTAP:
1138 return WIFI_INTERFACE_SOFTAP;
1139 case WLAN_HDD_P2P_CLIENT:
1140 return WIFI_INTERFACE_P2P_CLIENT;
1141 case WLAN_HDD_P2P_GO:
1142 return WIFI_INTERFACE_P2P_GO;
1143 case WLAN_HDD_IBSS:
1144 return WIFI_INTERFACE_IBSS;
1145 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301146 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301147 }
1148}
1149
1150static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1151 tpSirWifiInterfaceInfo pInfo)
1152{
1153 v_U8_t *staMac = NULL;
1154 hdd_station_ctx_t *pHddStaCtx;
1155 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1156 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1157
1158 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1159
1160 vos_mem_copy(pInfo->macAddr,
1161 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1162
1163 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1164 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1165 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1166 {
1167 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1168 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1169 {
1170 pInfo->state = WIFI_DISCONNECTED;
1171 }
1172 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1173 {
1174 hddLog(VOS_TRACE_LEVEL_ERROR,
1175 "%s: Session ID %d, Connection is in progress", __func__,
1176 pAdapter->sessionId);
1177 pInfo->state = WIFI_ASSOCIATING;
1178 }
1179 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1180 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1181 {
1182 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1183 hddLog(VOS_TRACE_LEVEL_ERROR,
1184 "%s: client " MAC_ADDRESS_STR
1185 " is in the middle of WPS/EAPOL exchange.", __func__,
1186 MAC_ADDR_ARRAY(staMac));
1187 pInfo->state = WIFI_AUTHENTICATING;
1188 }
1189 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1190 {
1191 pInfo->state = WIFI_ASSOCIATED;
1192 vos_mem_copy(pInfo->bssid,
1193 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1194 vos_mem_copy(pInfo->ssid,
1195 pHddStaCtx->conn_info.SSID.SSID.ssId,
1196 pHddStaCtx->conn_info.SSID.SSID.length);
1197 //NULL Terminate the string.
1198 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1199 }
1200 }
1201 vos_mem_copy(pInfo->countryStr,
1202 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1203
1204 vos_mem_copy(pInfo->apCountryStr,
1205 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1206
1207 return TRUE;
1208}
1209
1210/*
1211 * hdd_link_layer_process_peer_stats () - This function is called after
1212 * receiving Link Layer Peer statistics from FW.This function converts
1213 * the firmware data to the NL data and sends the same to the kernel/upper
1214 * layers.
1215 */
1216static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1217 v_VOID_t *pData)
1218{
1219 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1220 tpSirWifiRateStat pWifiRateStat;
1221 tpSirWifiPeerStat pWifiPeerStat;
1222 tpSirWifiPeerInfo pWifiPeerInfo;
1223 struct nlattr *peerInfo;
1224 struct sk_buff *vendor_event;
1225 int status, i;
1226
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301227 ENTER();
1228
Sunil Duttc69bccb2014-05-26 21:30:20 +05301229 status = wlan_hdd_validate_context(pHddCtx);
1230 if (0 != status)
1231 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301232 return;
1233 }
1234
1235 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1236
1237 hddLog(VOS_TRACE_LEVEL_INFO,
1238 "LL_STATS_PEER_ALL : numPeers %u",
1239 pWifiPeerStat->numPeers);
1240 {
1241 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1242 {
1243 pWifiPeerInfo = (tpSirWifiPeerInfo)
1244 ((uint8 *)pWifiPeerStat->peerInfo +
1245 ( i * sizeof(tSirWifiPeerInfo)));
1246
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301247 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1248 pWifiPeerInfo->type = WIFI_PEER_AP;
1249 }
1250 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1251 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1252 }
1253
Sunil Duttc69bccb2014-05-26 21:30:20 +05301254 hddLog(VOS_TRACE_LEVEL_INFO,
1255 " %d) LL_STATS Channel Stats "
1256 " Peer Type %u "
1257 " peerMacAddress %pM "
1258 " capabilities 0x%x "
1259 " numRate %u ",
1260 i,
1261 pWifiPeerInfo->type,
1262 pWifiPeerInfo->peerMacAddress,
1263 pWifiPeerInfo->capabilities,
1264 pWifiPeerInfo->numRate);
1265 {
1266 int j;
1267 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1268 {
1269 pWifiRateStat = (tpSirWifiRateStat)
1270 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1271 ( j * sizeof(tSirWifiRateStat)));
1272
1273 hddLog(VOS_TRACE_LEVEL_INFO,
1274 " peer Rate Stats "
1275 " preamble %u "
1276 " nss %u "
1277 " bw %u "
1278 " rateMcsIdx %u "
1279 " reserved %u "
1280 " bitrate %u "
1281 " txMpdu %u "
1282 " rxMpdu %u "
1283 " mpduLost %u "
1284 " retries %u "
1285 " retriesShort %u "
1286 " retriesLong %u",
1287 pWifiRateStat->rate.preamble,
1288 pWifiRateStat->rate.nss,
1289 pWifiRateStat->rate.bw,
1290 pWifiRateStat->rate.rateMcsIdx,
1291 pWifiRateStat->rate.reserved,
1292 pWifiRateStat->rate.bitrate,
1293 pWifiRateStat->txMpdu,
1294 pWifiRateStat->rxMpdu,
1295 pWifiRateStat->mpduLost,
1296 pWifiRateStat->retries,
1297 pWifiRateStat->retriesShort,
1298 pWifiRateStat->retriesLong);
1299 }
1300 }
1301 }
1302 }
1303
1304 /*
1305 * Allocate a size of 4096 for the peer stats comprising
1306 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1307 * sizeof (tSirWifiRateStat).Each field is put with an
1308 * NL attribute.The size of 4096 is considered assuming
1309 * that number of rates shall not exceed beyond 50 with
1310 * the sizeof (tSirWifiRateStat) being 32.
1311 */
1312 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1313 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1314 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1315 GFP_KERNEL);
1316 if (!vendor_event)
1317 {
1318 hddLog(VOS_TRACE_LEVEL_ERROR,
1319 "%s: cfg80211_vendor_event_alloc failed",
1320 __func__);
1321 return;
1322 }
1323 if (nla_put_u32(vendor_event,
1324 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1325 pWifiPeerStat->numPeers))
1326 {
1327 hddLog(VOS_TRACE_LEVEL_ERROR,
1328 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1329 kfree_skb(vendor_event);
1330 return;
1331 }
1332
1333 peerInfo = nla_nest_start(vendor_event,
1334 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301335 if(!peerInfo)
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1339 __func__);
1340 kfree_skb(vendor_event);
1341 return;
1342 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301343
1344 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1345 pWifiPeerStat->peerInfo);
1346
1347 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1348 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301349 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301350 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301351
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301352 if(!peers)
1353 {
1354 hddLog(VOS_TRACE_LEVEL_ERROR,
1355 "%s: peer stats put fail",
1356 __func__);
1357 kfree_skb(vendor_event);
1358 return;
1359 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301360 if (FALSE == put_wifi_peer_info(
1361 pWifiPeerInfo, vendor_event))
1362 {
1363 hddLog(VOS_TRACE_LEVEL_ERROR,
1364 "%s: put_wifi_peer_info put fail", __func__);
1365 kfree_skb(vendor_event);
1366 return;
1367 }
1368
1369 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1370 pWifiPeerStat->peerInfo +
1371 (i * sizeof(tSirWifiPeerInfo)) +
1372 (numRate * sizeof (tSirWifiRateStat)));
1373 nla_nest_end(vendor_event, peers);
1374 }
1375 nla_nest_end(vendor_event, peerInfo);
1376 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301377
1378 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301379}
1380
1381/*
1382 * hdd_link_layer_process_iface_stats () - This function is called after
1383 * receiving Link Layer Interface statistics from FW.This function converts
1384 * the firmware data to the NL data and sends the same to the kernel/upper
1385 * layers.
1386 */
1387static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1388 v_VOID_t *pData)
1389{
1390 tpSirWifiIfaceStat pWifiIfaceStat;
1391 struct sk_buff *vendor_event;
1392 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1393 int status;
1394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301395 ENTER();
1396
Sunil Duttc69bccb2014-05-26 21:30:20 +05301397 status = wlan_hdd_validate_context(pHddCtx);
1398 if (0 != status)
1399 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301400 return;
1401 }
1402 /*
1403 * Allocate a size of 4096 for the interface stats comprising
1404 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1405 * assuming that all these fit with in the limit.Please take
1406 * a call on the limit based on the data requirements on
1407 * interface statistics.
1408 */
1409 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1410 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1411 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1412 GFP_KERNEL);
1413 if (!vendor_event)
1414 {
1415 hddLog(VOS_TRACE_LEVEL_ERROR,
1416 FL("cfg80211_vendor_event_alloc failed") );
1417 return;
1418 }
1419
1420 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1421
Dino Mycle3b9536d2014-07-09 22:05:24 +05301422
1423 if (FALSE == hdd_get_interface_info( pAdapter,
1424 &pWifiIfaceStat->info))
1425 {
1426 hddLog(VOS_TRACE_LEVEL_ERROR,
1427 FL("hdd_get_interface_info get fail") );
1428 kfree_skb(vendor_event);
1429 return;
1430 }
1431
1432 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1433 vendor_event))
1434 {
1435 hddLog(VOS_TRACE_LEVEL_ERROR,
1436 FL("put_wifi_iface_stats fail") );
1437 kfree_skb(vendor_event);
1438 return;
1439 }
1440
Sunil Duttc69bccb2014-05-26 21:30:20 +05301441 hddLog(VOS_TRACE_LEVEL_INFO,
1442 "WMI_LINK_STATS_IFACE Data");
1443
1444 hddLog(VOS_TRACE_LEVEL_INFO,
1445 "LL_STATS_IFACE: "
1446 " Mode %u "
1447 " MAC %pM "
1448 " State %u "
1449 " Roaming %u "
1450 " capabilities 0x%x "
1451 " SSID %s "
1452 " BSSID %pM",
1453 pWifiIfaceStat->info.mode,
1454 pWifiIfaceStat->info.macAddr,
1455 pWifiIfaceStat->info.state,
1456 pWifiIfaceStat->info.roaming,
1457 pWifiIfaceStat->info.capabilities,
1458 pWifiIfaceStat->info.ssid,
1459 pWifiIfaceStat->info.bssid);
1460
1461 hddLog(VOS_TRACE_LEVEL_INFO,
1462 " AP country str: %c%c%c",
1463 pWifiIfaceStat->info.apCountryStr[0],
1464 pWifiIfaceStat->info.apCountryStr[1],
1465 pWifiIfaceStat->info.apCountryStr[2]);
1466
1467
1468 hddLog(VOS_TRACE_LEVEL_INFO,
1469 " Country Str Association: %c%c%c",
1470 pWifiIfaceStat->info.countryStr[0],
1471 pWifiIfaceStat->info.countryStr[1],
1472 pWifiIfaceStat->info.countryStr[2]);
1473
1474 hddLog(VOS_TRACE_LEVEL_INFO,
1475 " beaconRx %u "
1476 " mgmtRx %u "
1477 " mgmtActionRx %u "
1478 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301479 " rssiMgmt %d "
1480 " rssiData %d "
1481 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301482 pWifiIfaceStat->beaconRx,
1483 pWifiIfaceStat->mgmtRx,
1484 pWifiIfaceStat->mgmtActionRx,
1485 pWifiIfaceStat->mgmtActionTx,
1486 pWifiIfaceStat->rssiMgmt,
1487 pWifiIfaceStat->rssiData,
1488 pWifiIfaceStat->rssiAck );
1489
1490
1491 {
1492 int i;
1493 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1494 {
1495 hddLog(VOS_TRACE_LEVEL_INFO,
1496
1497 " %d) LL_STATS IFACE: "
1498 " ac: %u txMpdu: %u "
1499 " rxMpdu: %u txMcast: %u "
1500 " rxMcast: %u rxAmpdu: %u "
1501 " txAmpdu: %u mpduLost: %u "
1502 " retries: %u retriesShort: %u "
1503 " retriesLong: %u contentionTimeMin: %u "
1504 " contentionTimeMax: %u contentionTimeAvg: %u "
1505 " contentionNumSamples: %u",
1506 i,
1507 pWifiIfaceStat->AccessclassStats[i].ac,
1508 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1509 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1510 pWifiIfaceStat->AccessclassStats[i].txMcast,
1511 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1512 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1513 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1514 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1515 pWifiIfaceStat->AccessclassStats[i].retries,
1516 pWifiIfaceStat->
1517 AccessclassStats[i].retriesShort,
1518 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1519 pWifiIfaceStat->
1520 AccessclassStats[i].contentionTimeMin,
1521 pWifiIfaceStat->
1522 AccessclassStats[i].contentionTimeMax,
1523 pWifiIfaceStat->
1524 AccessclassStats[i].contentionTimeAvg,
1525 pWifiIfaceStat->
1526 AccessclassStats[i].contentionNumSamples);
1527
1528 }
1529 }
1530
Sunil Duttc69bccb2014-05-26 21:30:20 +05301531 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301532
1533 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301534}
1535
1536/*
1537 * hdd_link_layer_process_radio_stats () - This function is called after
1538 * receiving Link Layer Radio statistics from FW.This function converts
1539 * the firmware data to the NL data and sends the same to the kernel/upper
1540 * layers.
1541 */
1542static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1543 v_VOID_t *pData)
1544{
1545 int status, i;
1546 tpSirWifiRadioStat pWifiRadioStat;
1547 tpSirWifiChannelStats pWifiChannelStats;
1548 struct sk_buff *vendor_event;
1549 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1550 struct nlattr *chList;
1551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301552 ENTER();
1553
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554 status = wlan_hdd_validate_context(pHddCtx);
1555 if (0 != status)
1556 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301557 return;
1558 }
1559 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1560
1561 hddLog(VOS_TRACE_LEVEL_INFO,
1562 "LL_STATS_RADIO"
1563 " radio is %d onTime is %u "
1564 " txTime is %u rxTime is %u "
1565 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301566 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 " onTimePnoScan is %u onTimeHs20 is %u "
1568 " numChannels is %u",
1569 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1570 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1571 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301572 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301573 pWifiRadioStat->onTimeRoamScan,
1574 pWifiRadioStat->onTimePnoScan,
1575 pWifiRadioStat->onTimeHs20,
1576 pWifiRadioStat->numChannels);
1577 /*
1578 * Allocate a size of 4096 for the Radio stats comprising
1579 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1580 * (tSirWifiChannelStats).Each channel data is put with an
1581 * NL attribute.The size of 4096 is considered assuming that
1582 * number of channels shall not exceed beyond 60 with the
1583 * sizeof (tSirWifiChannelStats) being 24 bytes.
1584 */
1585
1586 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1587 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1588 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1589 GFP_KERNEL);
1590
1591 if (!vendor_event)
1592 {
1593 hddLog(VOS_TRACE_LEVEL_ERROR,
1594 FL("cfg80211_vendor_event_alloc failed") );
1595 return;
1596 }
1597
1598 if (nla_put_u32(vendor_event,
1599 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1600 pWifiRadioStat->radio) ||
1601 nla_put_u32(vendor_event,
1602 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1603 pWifiRadioStat->onTime) ||
1604 nla_put_u32(vendor_event,
1605 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1606 pWifiRadioStat->txTime) ||
1607 nla_put_u32(vendor_event,
1608 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1609 pWifiRadioStat->rxTime) ||
1610 nla_put_u32(vendor_event,
1611 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1612 pWifiRadioStat->onTimeScan) ||
1613 nla_put_u32(vendor_event,
1614 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1615 pWifiRadioStat->onTimeNbd) ||
1616 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301617 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1618 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 nla_put_u32(vendor_event,
1620 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1621 pWifiRadioStat->onTimeRoamScan) ||
1622 nla_put_u32(vendor_event,
1623 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1624 pWifiRadioStat->onTimePnoScan) ||
1625 nla_put_u32(vendor_event,
1626 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1627 pWifiRadioStat->onTimeHs20) ||
1628 nla_put_u32(vendor_event,
1629 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1630 pWifiRadioStat->numChannels))
1631 {
1632 hddLog(VOS_TRACE_LEVEL_ERROR,
1633 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1634 kfree_skb(vendor_event);
1635 return ;
1636 }
1637
1638 chList = nla_nest_start(vendor_event,
1639 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301640 if(!chList)
1641 {
1642 hddLog(VOS_TRACE_LEVEL_ERROR,
1643 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1644 __func__);
1645 kfree_skb(vendor_event);
1646 return;
1647 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301648 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1649 {
1650 struct nlattr *chInfo;
1651
1652 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1653 pWifiRadioStat->channels +
1654 (i * sizeof(tSirWifiChannelStats)));
1655
1656 hddLog(VOS_TRACE_LEVEL_INFO,
1657 " %d) Channel Info"
1658 " width is %u "
1659 " CenterFreq %u "
1660 " CenterFreq0 %u "
1661 " CenterFreq1 %u "
1662 " onTime %u "
1663 " ccaBusyTime %u",
1664 i,
1665 pWifiChannelStats->channel.width,
1666 pWifiChannelStats->channel.centerFreq,
1667 pWifiChannelStats->channel.centerFreq0,
1668 pWifiChannelStats->channel.centerFreq1,
1669 pWifiChannelStats->onTime,
1670 pWifiChannelStats->ccaBusyTime);
1671
1672
1673 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301674 if(!chInfo)
1675 {
1676 hddLog(VOS_TRACE_LEVEL_ERROR,
1677 "%s: failed to put chInfo",
1678 __func__);
1679 kfree_skb(vendor_event);
1680 return;
1681 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301682
1683 if (nla_put_u32(vendor_event,
1684 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1685 pWifiChannelStats->channel.width) ||
1686 nla_put_u32(vendor_event,
1687 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1688 pWifiChannelStats->channel.centerFreq) ||
1689 nla_put_u32(vendor_event,
1690 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1691 pWifiChannelStats->channel.centerFreq0) ||
1692 nla_put_u32(vendor_event,
1693 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1694 pWifiChannelStats->channel.centerFreq1) ||
1695 nla_put_u32(vendor_event,
1696 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1697 pWifiChannelStats->onTime) ||
1698 nla_put_u32(vendor_event,
1699 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1700 pWifiChannelStats->ccaBusyTime))
1701 {
1702 hddLog(VOS_TRACE_LEVEL_ERROR,
1703 FL("cfg80211_vendor_event_alloc failed") );
1704 kfree_skb(vendor_event);
1705 return ;
1706 }
1707 nla_nest_end(vendor_event, chInfo);
1708 }
1709 nla_nest_end(vendor_event, chList);
1710
1711 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301712
1713 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714 return;
1715}
1716
1717/*
1718 * hdd_link_layer_stats_ind_callback () - This function is called after
1719 * receiving Link Layer indications from FW.This callback converts the firmware
1720 * data to the NL data and send the same to the kernel/upper layers.
1721 */
1722static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1723 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301724 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301725{
Dino Mycled3d50022014-07-07 12:58:25 +05301726 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1727 hdd_adapter_t *pAdapter = NULL;
1728 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301729 int status;
1730
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301731 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301732
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301733 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734 if (0 != status)
1735 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736 return;
1737 }
1738
Dino Mycled3d50022014-07-07 12:58:25 +05301739 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1740 if (NULL == pAdapter)
1741 {
1742 hddLog(VOS_TRACE_LEVEL_ERROR,
1743 FL(" MAC address %pM does not exist with host"),
1744 macAddr);
1745 return;
1746 }
1747
Sunil Duttc69bccb2014-05-26 21:30:20 +05301748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301749 "%s: Interface: %s LLStats indType: %d", __func__,
1750 pAdapter->dev->name, indType);
1751
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 switch (indType)
1753 {
1754 case SIR_HAL_LL_STATS_RESULTS_RSP:
1755 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756 hddLog(VOS_TRACE_LEVEL_INFO,
1757 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1758 hddLog(VOS_TRACE_LEVEL_INFO,
1759 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1760 linkLayerStatsResults->paramId);
1761 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301762 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1763 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 hddLog(VOS_TRACE_LEVEL_INFO,
1765 "LL_STATS RESULTS RESPONSE respId = %u",
1766 linkLayerStatsResults->respId);
1767 hddLog(VOS_TRACE_LEVEL_INFO,
1768 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1769 linkLayerStatsResults->moreResultToFollow);
1770 hddLog(VOS_TRACE_LEVEL_INFO,
1771 "LL_STATS RESULTS RESPONSE result = %p",
1772 linkLayerStatsResults->result);
1773 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1774 {
1775 hdd_link_layer_process_radio_stats(pAdapter,
1776 (v_VOID_t *)linkLayerStatsResults->result);
1777 }
1778 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1779 {
1780 hdd_link_layer_process_iface_stats(pAdapter,
1781 (v_VOID_t *)linkLayerStatsResults->result);
1782 }
1783 else if ( linkLayerStatsResults->paramId &
1784 WMI_LINK_STATS_ALL_PEER )
1785 {
1786 hdd_link_layer_process_peer_stats(pAdapter,
1787 (v_VOID_t *)linkLayerStatsResults->result);
1788 } /* WMI_LINK_STATS_ALL_PEER */
1789 else
1790 {
1791 hddLog(VOS_TRACE_LEVEL_ERROR,
1792 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1793 }
1794
1795 break;
1796 }
1797 default:
1798 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1799 break;
1800 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301801
1802 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301803 return;
1804}
1805
1806const struct
1807nla_policy
1808qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1809{
1810 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1811 { .type = NLA_U32 },
1812 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1813 { .type = NLA_U32 },
1814};
1815
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301816static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1817 struct wireless_dev *wdev,
1818 const void *data,
1819 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820{
1821 int status;
1822 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301823 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301824 struct net_device *dev = wdev->netdev;
1825 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1826 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301827 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301828
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301829 ENTER();
1830
Sunil Duttc69bccb2014-05-26 21:30:20 +05301831 status = wlan_hdd_validate_context(pHddCtx);
1832 if (0 != status)
1833 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301834 return -EINVAL;
1835 }
1836
1837 if (NULL == pAdapter)
1838 {
1839 hddLog(VOS_TRACE_LEVEL_ERROR,
1840 FL("HDD adapter is Null"));
1841 return -ENODEV;
1842 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301843 /* check the LLStats Capability */
1844 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1845 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1846 {
1847 hddLog(VOS_TRACE_LEVEL_ERROR,
1848 FL("Link Layer Statistics not supported by Firmware"));
1849 return -EINVAL;
1850 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301851
1852 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1853 (struct nlattr *)data,
1854 data_len, qca_wlan_vendor_ll_set_policy))
1855 {
1856 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1857 return -EINVAL;
1858 }
1859 if (!tb_vendor
1860 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1861 {
1862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1863 return -EINVAL;
1864 }
1865 if (!tb_vendor[
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1867 {
1868 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1869 return -EINVAL;
1870 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301871 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301872 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301873
Dino Mycledf0a5d92014-07-04 09:41:55 +05301874 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301875 nla_get_u32(
1876 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1877
Dino Mycledf0a5d92014-07-04 09:41:55 +05301878 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301879 nla_get_u32(
1880 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1881
Dino Mycled3d50022014-07-07 12:58:25 +05301882 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1883 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301884
1885
1886 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301887 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301888 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301889 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890 hddLog(VOS_TRACE_LEVEL_INFO,
1891 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301892 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893 hddLog(VOS_TRACE_LEVEL_INFO,
1894 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896
1897 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1898 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301899 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900 {
1901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1902 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301903 return -EINVAL;
1904
1905 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301906
1907 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1908 if (VOS_STATUS_SUCCESS !=
1909 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1910 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1911 {
1912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1913 "WLANTL_ClearInterfaceStats Failed", __func__);
1914 return -EINVAL;
1915 }
1916
1917 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1918 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1919 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1920 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1921
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301923 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301924 {
1925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1926 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927 return -EINVAL;
1928 }
1929
1930 pAdapter->isLinkLayerStatsSet = 1;
1931
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301932 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933 return 0;
1934}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301935static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1936 struct wireless_dev *wdev,
1937 const void *data,
1938 int data_len)
1939{
1940 int ret = 0;
1941
1942 vos_ssr_protect(__func__);
1943 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1944 vos_ssr_unprotect(__func__);
1945
1946 return ret;
1947}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948
1949const struct
1950nla_policy
1951qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1952{
1953 /* Unsigned 32bit value provided by the caller issuing the GET stats
1954 * command. When reporting
1955 * the stats results, the driver uses the same value to indicate
1956 * which GET request the results
1957 * correspond to.
1958 */
1959 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1960
1961 /* Unsigned 32bit value . bit mask to identify what statistics are
1962 requested for retrieval */
1963 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1964};
1965
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301966static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1967 struct wireless_dev *wdev,
1968 const void *data,
1969 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301970{
1971 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1972 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301973 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301974 struct net_device *dev = wdev->netdev;
1975 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1976 int status;
1977
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301978 ENTER();
1979
Sunil Duttc69bccb2014-05-26 21:30:20 +05301980 status = wlan_hdd_validate_context(pHddCtx);
1981 if (0 != status)
1982 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301983 return -EINVAL ;
1984 }
1985
1986 if (NULL == pAdapter)
1987 {
1988 hddLog(VOS_TRACE_LEVEL_FATAL,
1989 "%s: HDD adapter is Null", __func__);
1990 return -ENODEV;
1991 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301992 /* check the LLStats Capability */
1993 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1994 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1995 {
1996 hddLog(VOS_TRACE_LEVEL_ERROR,
1997 FL("Link Layer Statistics not supported by Firmware"));
1998 return -EINVAL;
1999 }
2000
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001
2002 if (!pAdapter->isLinkLayerStatsSet)
2003 {
2004 hddLog(VOS_TRACE_LEVEL_FATAL,
2005 "%s: isLinkLayerStatsSet : %d",
2006 __func__, pAdapter->isLinkLayerStatsSet);
2007 return -EINVAL;
2008 }
2009
2010 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2011 (struct nlattr *)data,
2012 data_len, qca_wlan_vendor_ll_get_policy))
2013 {
2014 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2015 return -EINVAL;
2016 }
2017
2018 if (!tb_vendor
2019 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2020 {
2021 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2022 return -EINVAL;
2023 }
2024
2025 if (!tb_vendor
2026 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2027 {
2028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2029 return -EINVAL;
2030 }
2031
Sunil Duttc69bccb2014-05-26 21:30:20 +05302032
Dino Mycledf0a5d92014-07-04 09:41:55 +05302033 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302034 nla_get_u32( tb_vendor[
2035 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302036 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302037 nla_get_u32( tb_vendor[
2038 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2039
Dino Mycled3d50022014-07-07 12:58:25 +05302040 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2041 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302042
2043 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302044 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302046 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 hddLog(VOS_TRACE_LEVEL_INFO,
2048 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302049 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302050
2051 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302052 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302053 {
2054 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2055 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056 return -EINVAL;
2057 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302058
2059 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302060 return 0;
2061}
2062
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302063static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2064 struct wireless_dev *wdev,
2065 const void *data,
2066 int data_len)
2067{
2068 int ret = 0;
2069
2070 vos_ssr_protect(__func__);
2071 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2072 vos_ssr_unprotect(__func__);
2073
2074 return ret;
2075}
2076
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077const struct
2078nla_policy
2079qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2080{
2081 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2082 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2083 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2084 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2085};
2086
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302087static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2088 struct wireless_dev *wdev,
2089 const void *data,
2090 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091{
2092 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2093 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302094 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302095 struct net_device *dev = wdev->netdev;
2096 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2097 u32 statsClearReqMask;
2098 u8 stopReq;
2099 int status;
2100
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302101 ENTER();
2102
Sunil Duttc69bccb2014-05-26 21:30:20 +05302103 status = wlan_hdd_validate_context(pHddCtx);
2104 if (0 != status)
2105 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302106 return -EINVAL;
2107 }
2108
2109 if (NULL == pAdapter)
2110 {
2111 hddLog(VOS_TRACE_LEVEL_FATAL,
2112 "%s: HDD adapter is Null", __func__);
2113 return -ENODEV;
2114 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302115 /* check the LLStats Capability */
2116 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2117 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2118 {
2119 hddLog(VOS_TRACE_LEVEL_ERROR,
2120 FL("Enable LLStats Capability"));
2121 return -EINVAL;
2122 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302123
2124 if (!pAdapter->isLinkLayerStatsSet)
2125 {
2126 hddLog(VOS_TRACE_LEVEL_FATAL,
2127 "%s: isLinkLayerStatsSet : %d",
2128 __func__, pAdapter->isLinkLayerStatsSet);
2129 return -EINVAL;
2130 }
2131
2132 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2133 (struct nlattr *)data,
2134 data_len, qca_wlan_vendor_ll_clr_policy))
2135 {
2136 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2137 return -EINVAL;
2138 }
2139
2140 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2141
2142 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2143 {
2144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2145 return -EINVAL;
2146
2147 }
2148
Sunil Duttc69bccb2014-05-26 21:30:20 +05302149
Dino Mycledf0a5d92014-07-04 09:41:55 +05302150 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302151 nla_get_u32(
2152 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2153
Dino Mycledf0a5d92014-07-04 09:41:55 +05302154 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302155 nla_get_u8(
2156 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2157
2158 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302159 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302160
Dino Mycled3d50022014-07-07 12:58:25 +05302161 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2162 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302163
2164 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302165 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302166 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302167 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302168 hddLog(VOS_TRACE_LEVEL_INFO,
2169 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302170 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302171 hddLog(VOS_TRACE_LEVEL_INFO,
2172 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302173 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302174
2175 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302176 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302177 {
2178 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302179 hdd_station_ctx_t *pHddStaCtx;
2180
2181 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2182 if (VOS_STATUS_SUCCESS !=
2183 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2184 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2185 {
2186 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2187 "WLANTL_ClearInterfaceStats Failed", __func__);
2188 return -EINVAL;
2189 }
2190 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2191 (statsClearReqMask & WIFI_STATS_IFACE)) {
2192 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2193 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2194 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2195 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2196 }
2197
Sunil Duttc69bccb2014-05-26 21:30:20 +05302198 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2199 2 * sizeof(u32) +
2200 NLMSG_HDRLEN);
2201
2202 if (temp_skbuff != NULL)
2203 {
2204
2205 if (nla_put_u32(temp_skbuff,
2206 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2207 statsClearReqMask) ||
2208 nla_put_u32(temp_skbuff,
2209 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2210 stopReq))
2211 {
2212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2213 kfree_skb(temp_skbuff);
2214 return -EINVAL;
2215 }
2216 /* If the ask is to stop the stats collection as part of clear
2217 * (stopReq = 1) , ensure that no further requests of get
2218 * go to the firmware by having isLinkLayerStatsSet set to 0.
2219 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302220 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302221 * case the firmware is just asked to clear the statistics.
2222 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302223 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302224 pAdapter->isLinkLayerStatsSet = 0;
2225 return cfg80211_vendor_cmd_reply(temp_skbuff);
2226 }
2227 return -ENOMEM;
2228 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302229
2230 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302231 return -EINVAL;
2232}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302233static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2234 struct wireless_dev *wdev,
2235 const void *data,
2236 int data_len)
2237{
2238 int ret = 0;
2239
2240 vos_ssr_protect(__func__);
2241 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2242 vos_ssr_unprotect(__func__);
2243
2244 return ret;
2245
2246
2247}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302248#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2249
Dino Mycle6fb96c12014-06-10 11:52:40 +05302250#ifdef WLAN_FEATURE_EXTSCAN
2251static const struct nla_policy
2252wlan_hdd_extscan_config_policy
2253 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2254{
2255 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2256 { .type = NLA_U32 },
2257 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2258 { .type = NLA_U32 },
2259 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2261 { .type = NLA_U32 },
2262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2263 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2264
2265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2269 { .type = NLA_U8 },
2270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2271 { .type = NLA_U32 },
2272 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2273 { .type = NLA_U32 },
2274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2275 { .type = NLA_U32 },
2276 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2277 { .type = NLA_U8 },
2278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2279 { .type = NLA_U8 },
2280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2281 { .type = NLA_U8 },
2282
2283 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2284 { .type = NLA_U32 },
2285 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2286 { .type = NLA_UNSPEC },
2287 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2288 { .type = NLA_S32 },
2289 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2290 { .type = NLA_S32 },
2291 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2292 { .type = NLA_U32 },
2293 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2294 { .type = NLA_U32 },
2295 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2296 { .type = NLA_U32 },
2297 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2298 = { .type = NLA_U32 },
2299 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2300 { .type = NLA_U32 },
2301 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2302 NLA_U32 },
2303};
2304
2305static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2306{
2307 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2308 struct sk_buff *skb = NULL;
2309 tpSirEXTScanCapabilitiesEvent pData =
2310 (tpSirEXTScanCapabilitiesEvent) pMsg;
2311
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302312 ENTER();
2313
2314 if (wlan_hdd_validate_context(pHddCtx))
2315 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302316 return;
2317 }
2318
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302319 if (!pMsg)
2320 {
2321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2322 return;
2323 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302324 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2325 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2326 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2327 GFP_KERNEL);
2328
2329 if (!skb) {
2330 hddLog(VOS_TRACE_LEVEL_ERROR,
2331 FL("cfg80211_vendor_event_alloc failed"));
2332 return;
2333 }
2334
2335 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2336 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2337 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2338 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2339 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2340 pData->maxRssiSampleSize);
2341 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2342 pData->maxScanReportingThreshold);
2343 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2344 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2345 pData->maxSignificantWifiChangeAPs);
2346 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2347 pData->maxBsidHistoryEntries);
2348
2349 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2350 pData->requestId) ||
2351 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2352 nla_put_u32(skb,
2353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2354 pData->scanCacheSize) ||
2355 nla_put_u32(skb,
2356 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2357 pData->scanBuckets) ||
2358 nla_put_u32(skb,
2359 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2360 pData->maxApPerScan) ||
2361 nla_put_u32(skb,
2362 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2363 pData->maxRssiSampleSize) ||
2364 nla_put_u32(skb,
2365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2366 pData->maxScanReportingThreshold) ||
2367 nla_put_u32(skb,
2368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2369 pData->maxHotlistAPs) ||
2370 nla_put_u32(skb,
2371 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2372 pData->maxSignificantWifiChangeAPs) ||
2373 nla_put_u32(skb,
2374 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2375 pData->maxBsidHistoryEntries)) {
2376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2377 goto nla_put_failure;
2378 }
2379
2380 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302381 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302382 return;
2383
2384nla_put_failure:
2385 kfree_skb(skb);
2386 return;
2387}
2388
2389
2390static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2391{
2392 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2393 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2394 struct sk_buff *skb = NULL;
2395 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2396
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302397 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302398
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302399 if (wlan_hdd_validate_context(pHddCtx)){
2400 return;
2401 }
2402 if (!pMsg)
2403 {
2404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405 return;
2406 }
2407
2408 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2409 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2410 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2411 GFP_KERNEL);
2412
2413 if (!skb) {
2414 hddLog(VOS_TRACE_LEVEL_ERROR,
2415 FL("cfg80211_vendor_event_alloc failed"));
2416 return;
2417 }
2418 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2419 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2420 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2421
2422 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2423 pData->requestId) ||
2424 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2425 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2426 goto nla_put_failure;
2427 }
2428
2429 /*
2430 * Store the Request ID for comparing with the requestID obtained
2431 * in other requests.HDD shall return a failure is the extscan_stop
2432 * request is issued with a different requestId as that of the
2433 * extscan_start request. Also, This requestId shall be used while
2434 * indicating the full scan results to the upper layers.
2435 * The requestId is stored with the assumption that the firmware
2436 * shall return the ext scan start request's requestId in ext scan
2437 * start response.
2438 */
2439 if (pData->status == 0)
2440 pMac->sme.extScanStartReqId = pData->requestId;
2441
2442
2443 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302444 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302445 return;
2446
2447nla_put_failure:
2448 kfree_skb(skb);
2449 return;
2450}
2451
2452
2453static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2454{
2455 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2456 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2457 struct sk_buff *skb = NULL;
2458
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302459 ENTER();
2460
2461 if (wlan_hdd_validate_context(pHddCtx)){
2462 return;
2463 }
2464 if (!pMsg)
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302467 return;
2468 }
2469
2470 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2471 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2472 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2473 GFP_KERNEL);
2474
2475 if (!skb) {
2476 hddLog(VOS_TRACE_LEVEL_ERROR,
2477 FL("cfg80211_vendor_event_alloc failed"));
2478 return;
2479 }
2480 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2481 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2482
2483 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2484 pData->requestId) ||
2485 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2487 goto nla_put_failure;
2488 }
2489
2490 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302491 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492 return;
2493
2494nla_put_failure:
2495 kfree_skb(skb);
2496 return;
2497}
2498
2499
2500static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2501 void *pMsg)
2502{
2503 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2504 struct sk_buff *skb = NULL;
2505 tpSirEXTScanSetBssidHotListRspParams pData =
2506 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2507
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302508 ENTER();
2509
2510 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302511 return;
2512 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302513 if (!pMsg)
2514 {
2515 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2516 return;
2517 }
2518
Dino Mycle6fb96c12014-06-10 11:52:40 +05302519 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2520 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2521 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2522 GFP_KERNEL);
2523
2524 if (!skb) {
2525 hddLog(VOS_TRACE_LEVEL_ERROR,
2526 FL("cfg80211_vendor_event_alloc failed"));
2527 return;
2528 }
2529 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2530 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2531 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2532
2533 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2534 pData->requestId) ||
2535 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2537 goto nla_put_failure;
2538 }
2539
2540 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302541 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302542 return;
2543
2544nla_put_failure:
2545 kfree_skb(skb);
2546 return;
2547}
2548
2549static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2550 void *pMsg)
2551{
2552 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2553 struct sk_buff *skb = NULL;
2554 tpSirEXTScanResetBssidHotlistRspParams pData =
2555 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2556
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302557 ENTER();
2558
2559 if (wlan_hdd_validate_context(pHddCtx)) {
2560 return;
2561 }
2562 if (!pMsg)
2563 {
2564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302565 return;
2566 }
2567
2568 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2569 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2570 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2571 GFP_KERNEL);
2572
2573 if (!skb) {
2574 hddLog(VOS_TRACE_LEVEL_ERROR,
2575 FL("cfg80211_vendor_event_alloc failed"));
2576 return;
2577 }
2578 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2580
2581 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2582 pData->requestId) ||
2583 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2585 goto nla_put_failure;
2586 }
2587
2588 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302589 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302590 return;
2591
2592nla_put_failure:
2593 kfree_skb(skb);
2594 return;
2595}
2596
2597
2598static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2599 void *pMsg)
2600{
2601 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2602 struct sk_buff *skb = NULL;
2603 tpSirEXTScanSetSignificantChangeRspParams pData =
2604 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302606 ENTER();
2607
2608 if (wlan_hdd_validate_context(pHddCtx)) {
2609 return;
2610 }
2611 if (!pMsg)
2612 {
2613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614 return;
2615 }
2616
2617 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2618 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2619 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2620 GFP_KERNEL);
2621
2622 if (!skb) {
2623 hddLog(VOS_TRACE_LEVEL_ERROR,
2624 FL("cfg80211_vendor_event_alloc failed"));
2625 return;
2626 }
2627 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2628 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2629 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2630
2631 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2632 pData->requestId) ||
2633 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2635 goto nla_put_failure;
2636 }
2637
2638 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302639 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640 return;
2641
2642nla_put_failure:
2643 kfree_skb(skb);
2644 return;
2645}
2646
2647
2648static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2649 void *pMsg)
2650{
2651 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2652 struct sk_buff *skb = NULL;
2653 tpSirEXTScanResetSignificantChangeRspParams pData =
2654 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2655
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302656 ENTER();
2657
2658 if (wlan_hdd_validate_context(pHddCtx)) {
2659 return;
2660 }
2661 if (!pMsg)
2662 {
2663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302664 return;
2665 }
2666
2667 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2668 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2669 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2670 GFP_KERNEL);
2671
2672 if (!skb) {
2673 hddLog(VOS_TRACE_LEVEL_ERROR,
2674 FL("cfg80211_vendor_event_alloc failed"));
2675 return;
2676 }
2677 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2678 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2679 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2680
2681 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2682 pData->requestId) ||
2683 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2685 goto nla_put_failure;
2686 }
2687
2688 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302689 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302690 return;
2691
2692nla_put_failure:
2693 kfree_skb(skb);
2694 return;
2695}
2696
2697static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2698 void *pMsg)
2699{
2700 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2701 struct sk_buff *skb = NULL;
2702 tANI_U32 i = 0, j, resultsPerEvent;
2703 tANI_S32 totalResults;
2704 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2705 tpSirWifiScanResult pSirWifiScanResult;
2706
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302707 ENTER();
2708
2709 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302710 return;
2711 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302712 if (!pMsg)
2713 {
2714 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2715 return;
2716 }
2717
Dino Mycle6fb96c12014-06-10 11:52:40 +05302718 totalResults = pData->numOfAps;
2719 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2720 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2721 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2722
2723 do{
2724 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2725 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2726 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2727
2728 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2729 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2730 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2731 GFP_KERNEL);
2732
2733 if (!skb) {
2734 hddLog(VOS_TRACE_LEVEL_ERROR,
2735 FL("cfg80211_vendor_event_alloc failed"));
2736 return;
2737 }
2738
2739 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2740
2741 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2742 pData->requestId) ||
2743 nla_put_u32(skb,
2744 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2745 resultsPerEvent)) {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2747 goto fail;
2748 }
2749 if (nla_put_u8(skb,
2750 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2751 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2752 {
2753 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2754 goto fail;
2755 }
2756
2757 if (resultsPerEvent) {
2758 struct nlattr *aps;
2759
2760 aps = nla_nest_start(skb,
2761 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2762 if (!aps)
2763 {
2764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2765 goto fail;
2766 }
2767
2768 for (j = 0; j < resultsPerEvent; j++, i++) {
2769 struct nlattr *ap;
2770 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2771 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2772
2773 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2774 "Ssid (%s)"
2775 "Bssid: %pM "
2776 "Channel (%u)"
2777 "Rssi (%d)"
2778 "RTT (%u)"
2779 "RTT_SD (%u)",
2780 i,
2781 pSirWifiScanResult->ts,
2782 pSirWifiScanResult->ssid,
2783 pSirWifiScanResult->bssid,
2784 pSirWifiScanResult->channel,
2785 pSirWifiScanResult->rssi,
2786 pSirWifiScanResult->rtt,
2787 pSirWifiScanResult->rtt_sd);
2788
2789 ap = nla_nest_start(skb, j + 1);
2790 if (!ap)
2791 {
2792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2793 goto fail;
2794 }
2795
2796 if (nla_put_u64(skb,
2797 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2798 pSirWifiScanResult->ts) )
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2801 goto fail;
2802 }
2803 if (nla_put(skb,
2804 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2805 sizeof(pSirWifiScanResult->ssid),
2806 pSirWifiScanResult->ssid) )
2807 {
2808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2809 goto fail;
2810 }
2811 if (nla_put(skb,
2812 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2813 sizeof(pSirWifiScanResult->bssid),
2814 pSirWifiScanResult->bssid) )
2815 {
2816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2817 goto fail;
2818 }
2819 if (nla_put_u32(skb,
2820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2821 pSirWifiScanResult->channel) )
2822 {
2823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2824 goto fail;
2825 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302826 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302827 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2828 pSirWifiScanResult->rssi) )
2829 {
2830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2831 goto fail;
2832 }
2833 if (nla_put_u32(skb,
2834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2835 pSirWifiScanResult->rtt) )
2836 {
2837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2838 goto fail;
2839 }
2840 if (nla_put_u32(skb,
2841 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2842 pSirWifiScanResult->rtt_sd))
2843 {
2844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2845 goto fail;
2846 }
2847
2848 nla_nest_end(skb, ap);
2849 }
2850 nla_nest_end(skb, aps);
2851
2852 }
2853 cfg80211_vendor_event(skb, GFP_KERNEL);
2854 } while (totalResults > 0);
2855
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302856 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302857 return;
2858fail:
2859 kfree_skb(skb);
2860 return;
2861}
2862
2863static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2864 void *pMsg)
2865{
2866 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2867 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2868 struct sk_buff *skb = NULL;
2869 tANI_U32 i;
2870
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302871 ENTER();
2872
2873 if (wlan_hdd_validate_context(pHddCtx)) {
2874 return;
2875 }
2876 if (!pMsg)
2877 {
2878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302879 return;
2880 }
2881
2882 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2883 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2884 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2885 GFP_KERNEL);
2886
2887 if (!skb) {
2888 hddLog(VOS_TRACE_LEVEL_ERROR,
2889 FL("cfg80211_vendor_event_alloc failed"));
2890 return;
2891 }
2892 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2893 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2894 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2895 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2896
2897 for (i = 0; i < pData->numOfAps; i++) {
2898 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2899 "Ssid (%s) "
2900 "Bssid (" MAC_ADDRESS_STR ") "
2901 "Channel (%u) "
2902 "Rssi (%d) "
2903 "RTT (%u) "
2904 "RTT_SD (%u) ",
2905 i,
2906 pData->ap[i].ts,
2907 pData->ap[i].ssid,
2908 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2909 pData->ap[i].channel,
2910 pData->ap[i].rssi,
2911 pData->ap[i].rtt,
2912 pData->ap[i].rtt_sd);
2913 }
2914
2915 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2916 pData->requestId) ||
2917 nla_put_u32(skb,
2918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2919 pData->numOfAps)) {
2920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2921 goto fail;
2922 }
2923 if (pData->numOfAps) {
2924 struct nlattr *aps;
2925
2926 aps = nla_nest_start(skb,
2927 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2928 if (!aps)
2929 goto fail;
2930
2931 for (i = 0; i < pData->numOfAps; i++) {
2932 struct nlattr *ap;
2933
2934 ap = nla_nest_start(skb, i + 1);
2935 if (!ap)
2936 goto fail;
2937
2938 if (nla_put_u64(skb,
2939 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2940 pData->ap[i].ts) ||
2941 nla_put(skb,
2942 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2943 sizeof(pData->ap[i].ssid),
2944 pData->ap[i].ssid) ||
2945 nla_put(skb,
2946 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2947 sizeof(pData->ap[i].bssid),
2948 pData->ap[i].bssid) ||
2949 nla_put_u32(skb,
2950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2951 pData->ap[i].channel) ||
2952 nla_put_s32(skb,
2953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2954 pData->ap[i].rssi) ||
2955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2957 pData->ap[i].rtt) ||
2958 nla_put_u32(skb,
2959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2960 pData->ap[i].rtt_sd))
2961 goto fail;
2962
2963 nla_nest_end(skb, ap);
2964 }
2965 nla_nest_end(skb, aps);
2966
2967 if (nla_put_u8(skb,
2968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2969 pData->moreData))
2970 goto fail;
2971 }
2972
2973 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302974 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302975 return;
2976
2977fail:
2978 kfree_skb(skb);
2979 return;
2980
2981}
2982static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2983 void *pMsg)
2984{
2985 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2986 struct sk_buff *skb = NULL;
2987 tANI_U32 i, j;
2988 tpSirWifiSignificantChangeEvent pData =
2989 (tpSirWifiSignificantChangeEvent) pMsg;
2990
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302991 ENTER();
2992
2993 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302994 return;
2995 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302996 if (!pMsg)
2997 {
2998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2999 return;
3000 }
3001
Dino Mycle6fb96c12014-06-10 11:52:40 +05303002 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3003 EXTSCAN_EVENT_BUF_SIZE,
3004 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3005 GFP_KERNEL);
3006
3007 if (!skb) {
3008 hddLog(VOS_TRACE_LEVEL_ERROR,
3009 FL("cfg80211_vendor_event_alloc failed"));
3010 return;
3011 }
3012 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3013 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3014 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3015 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3016 pData->numSigRssiBss);
3017 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3018
3019 for (i = 0; i < pData->numSigRssiBss; i++) {
3020 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3021 " num RSSI %u ",
3022 i, pData->sigRssiResult[i].bssid,
3023 pData->sigRssiResult[i].channel,
3024 pData->sigRssiResult[i].numRssi);
3025
3026 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3027
3028 hddLog(VOS_TRACE_LEVEL_INFO,
3029 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303030 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303031
3032 }
3033 }
3034
3035
3036 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3037 pData->requestId) ||
3038 nla_put_u32(skb,
3039 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3040 pData->numSigRssiBss)) {
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3042 goto fail;
3043 }
3044
3045 if (pData->numSigRssiBss) {
3046 struct nlattr *aps;
3047 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3048 if (!aps)
3049 goto fail;
3050 for (i = 0; i < pData->numSigRssiBss; i++) {
3051 struct nlattr *ap;
3052
3053 ap = nla_nest_start(skb, i);
3054 if (!ap)
3055 goto fail;
3056 if (nla_put(skb,
3057 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3058 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3059 nla_put_u32(skb,
3060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3061 pData->sigRssiResult[i].channel) ||
3062 nla_put_u32(skb,
3063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3064 pData->sigRssiResult[i].numRssi) ||
3065 nla_put(skb,
3066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3067 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3068 pData->sigRssiResult[i].rssi))
3069 goto fail;
3070 nla_nest_end(skb, ap);
3071 }
3072 nla_nest_end(skb, aps);
3073 if (nla_put_u8(skb,
3074 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3075 pData->moreData))
3076 goto fail;
3077 }
3078 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303079 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303080 return;
3081fail:
3082 kfree_skb(skb);
3083 return;
3084}
3085
3086static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3087 void *pMsg)
3088{
3089 struct sk_buff *skb;
3090 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3091 tpSirWifiFullScanResultEvent pData =
3092 (tpSirWifiFullScanResultEvent) (pMsg);
3093
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303094 ENTER();
3095
3096 if (wlan_hdd_validate_context(pHddCtx)) {
3097 return;
3098 }
3099 if (!pMsg)
3100 {
3101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303102 return;
3103 }
3104
3105 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3106 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3107 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3108 GFP_KERNEL);
3109
3110 if (!skb) {
3111 hddLog(VOS_TRACE_LEVEL_ERROR,
3112 FL("cfg80211_vendor_event_alloc failed"));
3113 return;
3114 }
3115
3116 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3117 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3118 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3119 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3120 "Ssid (%s)"
3121 "Bssid (" MAC_ADDRESS_STR ")"
3122 "Channel (%u)"
3123 "Rssi (%d)"
3124 "RTT (%u)"
3125 "RTT_SD (%u)"),
3126 pData->ap.ts,
3127 pData->ap.ssid,
3128 MAC_ADDR_ARRAY(pData->ap.bssid),
3129 pData->ap.channel,
3130 pData->ap.rssi,
3131 pData->ap.rtt,
3132 pData->ap.rtt_sd);
3133 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3134 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3135 pData->requestId) ||
3136 nla_put_u64(skb,
3137 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3138 pData->ap.ts) ||
3139 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3140 sizeof(pData->ap.ssid),
3141 pData->ap.ssid) ||
3142 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3143 WNI_CFG_BSSID_LEN,
3144 pData->ap.bssid) ||
3145 nla_put_u32(skb,
3146 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3147 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303148 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303149 pData->ap.rssi) ||
3150 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3151 pData->ap.rtt) ||
3152 nla_put_u32(skb,
3153 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3154 pData->ap.rtt_sd) ||
3155 nla_put_u16(skb,
3156 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3157 pData->ap.beaconPeriod) ||
3158 nla_put_u16(skb,
3159 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3160 pData->ap.capability) ||
3161 nla_put_u32(skb,
3162 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3163 pData->ieLength))
3164 {
3165 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3166 goto nla_put_failure;
3167 }
3168 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3169 pData->ieLength,
3170 pData->ie))
3171 {
3172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3173 goto nla_put_failure;
3174 }
3175
3176 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303177 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303178 return;
3179
3180nla_put_failure:
3181 kfree_skb(skb);
3182 return;
3183}
3184
3185static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3186 void *pMsg)
3187{
3188 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3189 struct sk_buff *skb = NULL;
3190 tpSirEXTScanResultsAvailableIndParams pData =
3191 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3192
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303193 ENTER();
3194
3195 if (wlan_hdd_validate_context(pHddCtx)){
3196 return;
3197 }
3198 if (!pMsg)
3199 {
3200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303201 return;
3202 }
3203
3204 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3205 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3206 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3207 GFP_KERNEL);
3208
3209 if (!skb) {
3210 hddLog(VOS_TRACE_LEVEL_ERROR,
3211 FL("cfg80211_vendor_event_alloc failed"));
3212 return;
3213 }
3214
3215 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3216 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3217 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3218 pData->numResultsAvailable);
3219 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3220 pData->requestId) ||
3221 nla_put_u32(skb,
3222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3223 pData->numResultsAvailable)) {
3224 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3225 goto nla_put_failure;
3226 }
3227
3228 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303229 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303230 return;
3231
3232nla_put_failure:
3233 kfree_skb(skb);
3234 return;
3235}
3236
3237static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3238{
3239 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3240 struct sk_buff *skb = NULL;
3241 tpSirEXTScanProgressIndParams pData =
3242 (tpSirEXTScanProgressIndParams) pMsg;
3243
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303244 ENTER();
3245
3246 if (wlan_hdd_validate_context(pHddCtx)){
3247 return;
3248 }
3249 if (!pMsg)
3250 {
3251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 return;
3253 }
3254
3255 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
3256 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3257 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3258 GFP_KERNEL);
3259
3260 if (!skb) {
3261 hddLog(VOS_TRACE_LEVEL_ERROR,
3262 FL("cfg80211_vendor_event_alloc failed"));
3263 return;
3264 }
3265 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3266 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3267 pData->extScanEventType);
3268 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3269 pData->status);
3270
3271 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3272 pData->extScanEventType) ||
3273 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303274 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3275 pData->requestId) ||
3276 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3278 pData->status)) {
3279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3280 goto nla_put_failure;
3281 }
3282
3283 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303284 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303285 return;
3286
3287nla_put_failure:
3288 kfree_skb(skb);
3289 return;
3290}
3291
3292void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3293 void *pMsg)
3294{
3295 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3296
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303297 ENTER();
3298
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303300 return;
3301 }
3302
3303 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3304
3305
3306 switch(evType) {
3307 case SIR_HAL_EXTSCAN_START_RSP:
3308 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3309 break;
3310
3311 case SIR_HAL_EXTSCAN_STOP_RSP:
3312 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3313 break;
3314 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3315 /* There is no need to send this response to upper layer
3316 Just log the message */
3317 hddLog(VOS_TRACE_LEVEL_INFO,
3318 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3319 break;
3320 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3321 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3322 break;
3323
3324 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3325 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3326 break;
3327
3328 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3329 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3330 break;
3331
3332 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3333 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3334 break;
3335 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3336 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3337 break;
3338 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3339 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3340 break;
3341 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3342 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3343 break;
3344 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3345 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3346 break;
3347 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3348 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3349 break;
3350 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3351 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3352 break;
3353 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3354 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3355 break;
3356 default:
3357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3358 break;
3359 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303361}
3362
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303363static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3364 struct wireless_dev *wdev,
3365 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303366{
Dino Myclee8843b32014-07-04 14:21:45 +05303367 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368 struct net_device *dev = wdev->netdev;
3369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3370 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3371 struct nlattr
3372 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3373 eHalStatus status;
3374
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303375 ENTER();
3376
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377 status = wlan_hdd_validate_context(pHddCtx);
3378 if (0 != status)
3379 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303380 return -EINVAL;
3381 }
Dino Myclee8843b32014-07-04 14:21:45 +05303382 /* check the EXTScan Capability */
3383 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3384 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3385 {
3386 hddLog(VOS_TRACE_LEVEL_ERROR,
3387 FL("EXTScan not enabled/supported by Firmware"));
3388 return -EINVAL;
3389 }
3390
Dino Mycle6fb96c12014-06-10 11:52:40 +05303391 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3392 data, dataLen,
3393 wlan_hdd_extscan_config_policy)) {
3394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3395 return -EINVAL;
3396 }
3397
3398 /* Parse and fetch request Id */
3399 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3401 return -EINVAL;
3402 }
3403
Dino Mycle6fb96c12014-06-10 11:52:40 +05303404
Dino Myclee8843b32014-07-04 14:21:45 +05303405 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303406 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303407 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303408
Dino Myclee8843b32014-07-04 14:21:45 +05303409 reqMsg.sessionId = pAdapter->sessionId;
3410 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303411
Dino Myclee8843b32014-07-04 14:21:45 +05303412 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 if (!HAL_STATUS_SUCCESS(status)) {
3414 hddLog(VOS_TRACE_LEVEL_ERROR,
3415 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303416 return -EINVAL;
3417 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303418 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303419 return 0;
3420}
3421
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303422static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3423 struct wireless_dev *wdev,
3424 const void *data, int dataLen)
3425{
3426 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303427
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303428 vos_ssr_protect(__func__);
3429 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3430 vos_ssr_unprotect(__func__);
3431
3432 return ret;
3433}
3434
3435static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3436 struct wireless_dev *wdev,
3437 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303438{
Dino Myclee8843b32014-07-04 14:21:45 +05303439 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303440 struct net_device *dev = wdev->netdev;
3441 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3442 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3443 struct nlattr
3444 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3445 eHalStatus status;
3446
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303447 ENTER();
3448
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 status = wlan_hdd_validate_context(pHddCtx);
3450 if (0 != status)
3451 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452 return -EINVAL;
3453 }
Dino Myclee8843b32014-07-04 14:21:45 +05303454 /* check the EXTScan Capability */
3455 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3456 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3457 {
3458 hddLog(VOS_TRACE_LEVEL_ERROR,
3459 FL("EXTScan not enabled/supported by Firmware"));
3460 return -EINVAL;
3461 }
3462
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3464 data, dataLen,
3465 wlan_hdd_extscan_config_policy)) {
3466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3467 return -EINVAL;
3468 }
3469 /* Parse and fetch request Id */
3470 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3472 return -EINVAL;
3473 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474
Dino Myclee8843b32014-07-04 14:21:45 +05303475 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3477
Dino Myclee8843b32014-07-04 14:21:45 +05303478 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479
Dino Myclee8843b32014-07-04 14:21:45 +05303480 reqMsg.sessionId = pAdapter->sessionId;
3481 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482
3483 /* Parse and fetch flush parameter */
3484 if (!tb
3485 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3486 {
3487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3488 goto failed;
3489 }
Dino Myclee8843b32014-07-04 14:21:45 +05303490 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3492
Dino Myclee8843b32014-07-04 14:21:45 +05303493 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494
Dino Myclee8843b32014-07-04 14:21:45 +05303495 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303496 if (!HAL_STATUS_SUCCESS(status)) {
3497 hddLog(VOS_TRACE_LEVEL_ERROR,
3498 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 return -EINVAL;
3500 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303501 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 return 0;
3503
3504failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303505 return -EINVAL;
3506}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303507static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3508 struct wireless_dev *wdev,
3509 const void *data, int dataLen)
3510{
3511 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303513 vos_ssr_protect(__func__);
3514 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3515 vos_ssr_unprotect(__func__);
3516
3517 return ret;
3518}
3519
3520static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303522 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523{
3524 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3525 struct net_device *dev = wdev->netdev;
3526 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3527 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3528 struct nlattr
3529 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3530 struct nlattr
3531 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3532 struct nlattr *apTh;
3533 eHalStatus status;
3534 tANI_U8 i = 0;
3535 int rem;
3536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303537 ENTER();
3538
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539 status = wlan_hdd_validate_context(pHddCtx);
3540 if (0 != status)
3541 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542 return -EINVAL;
3543 }
Dino Myclee8843b32014-07-04 14:21:45 +05303544 /* check the EXTScan Capability */
3545 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3546 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3547 {
3548 hddLog(VOS_TRACE_LEVEL_ERROR,
3549 FL("EXTScan not enabled/supported by Firmware"));
3550 return -EINVAL;
3551 }
3552
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3554 data, dataLen,
3555 wlan_hdd_extscan_config_policy)) {
3556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3557 return -EINVAL;
3558 }
3559
3560 /* Parse and fetch request Id */
3561 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3563 return -EINVAL;
3564 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3566 vos_mem_malloc(sizeof(*pReqMsg));
3567 if (!pReqMsg) {
3568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3569 return -ENOMEM;
3570 }
3571
Dino Myclee8843b32014-07-04 14:21:45 +05303572
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 pReqMsg->requestId = nla_get_u32(
3574 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3575 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3576
3577 /* Parse and fetch number of APs */
3578 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3580 goto fail;
3581 }
3582
3583 pReqMsg->sessionId = pAdapter->sessionId;
3584 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3585
3586 pReqMsg->numAp = nla_get_u32(
3587 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3589
3590 nla_for_each_nested(apTh,
3591 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3592 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3593 nla_data(apTh), nla_len(apTh),
3594 NULL)) {
3595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3596 goto fail;
3597 }
3598
3599 /* Parse and fetch MAC address */
3600 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3602 goto fail;
3603 }
3604 memcpy(pReqMsg->ap[i].bssid, nla_data(
3605 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3606 sizeof(tSirMacAddr));
3607 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3608
3609 /* Parse and fetch low RSSI */
3610 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3612 goto fail;
3613 }
3614 pReqMsg->ap[i].low = nla_get_s32(
3615 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3616 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3617
3618 /* Parse and fetch high RSSI */
3619 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3621 goto fail;
3622 }
3623 pReqMsg->ap[i].high = nla_get_s32(
3624 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3625 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3626 pReqMsg->ap[i].high);
3627
3628 /* Parse and fetch channel */
3629 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3631 goto fail;
3632 }
3633 pReqMsg->ap[i].channel = nla_get_u32(
3634 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3635 hddLog(VOS_TRACE_LEVEL_INFO,
3636 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3637 i++;
3638 }
3639 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3640 if (!HAL_STATUS_SUCCESS(status)) {
3641 hddLog(VOS_TRACE_LEVEL_ERROR,
3642 FL("sme_SetBssHotlist failed(err=%d)"), status);
3643 vos_mem_free(pReqMsg);
3644 return -EINVAL;
3645 }
3646
Dino Myclee8843b32014-07-04 14:21:45 +05303647 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303648 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303649 return 0;
3650
3651fail:
3652 vos_mem_free(pReqMsg);
3653 return -EINVAL;
3654}
3655
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303656static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3657 struct wireless_dev *wdev,
3658 const void *data, int dataLen)
3659{
3660 int ret = 0;
3661
3662 vos_ssr_protect(__func__);
3663 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3664 dataLen);
3665 vos_ssr_unprotect(__func__);
3666
3667 return ret;
3668}
3669
3670static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303672 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673{
3674 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3675 struct net_device *dev = wdev->netdev;
3676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3677 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3678 struct nlattr
3679 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3680 struct nlattr
3681 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3682 struct nlattr *apTh;
3683 eHalStatus status;
3684 int i = 0;
3685 int rem;
3686
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303687 ENTER();
3688
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 status = wlan_hdd_validate_context(pHddCtx);
3690 if (0 != status)
3691 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 return -EINVAL;
3693 }
Dino Myclee8843b32014-07-04 14:21:45 +05303694 /* check the EXTScan Capability */
3695 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3696 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3697 {
3698 hddLog(VOS_TRACE_LEVEL_ERROR,
3699 FL("EXTScan not enabled/supported by Firmware"));
3700 return -EINVAL;
3701 }
3702
Dino Mycle6fb96c12014-06-10 11:52:40 +05303703 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3704 data, dataLen,
3705 wlan_hdd_extscan_config_policy)) {
3706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3707 return -EINVAL;
3708 }
3709
3710 /* Parse and fetch request Id */
3711 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3713 return -EINVAL;
3714 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303716 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303717 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3719 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303720 }
3721
Dino Myclee8843b32014-07-04 14:21:45 +05303722
3723
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724 pReqMsg->requestId = nla_get_u32(
3725 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3727
3728 /* Parse and fetch RSSI sample size */
3729 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3730 {
3731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3732 goto fail;
3733 }
3734 pReqMsg->rssiSampleSize = nla_get_u32(
3735 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3736 hddLog(VOS_TRACE_LEVEL_INFO,
3737 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3738
3739 /* Parse and fetch lost AP sample size */
3740 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3741 {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3743 goto fail;
3744 }
3745 pReqMsg->lostApSampleSize = nla_get_u32(
3746 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3747 hddLog(VOS_TRACE_LEVEL_INFO,
3748 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3749 /* Parse and fetch minimum Breaching */
3750 if (!tb
3751 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3753 goto fail;
3754 }
3755 pReqMsg->minBreaching = nla_get_u32(
3756 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3757 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3758
3759 /* Parse and fetch number of APs */
3760 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3762 goto fail;
3763 }
3764 pReqMsg->numAp = nla_get_u32(
3765 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3766 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3767
3768 pReqMsg->sessionId = pAdapter->sessionId;
3769 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3770
3771 nla_for_each_nested(apTh,
3772 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3773 if(nla_parse(tb2,
3774 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3775 nla_data(apTh), nla_len(apTh),
3776 NULL)) {
3777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3778 goto fail;
3779 }
3780
3781 /* Parse and fetch MAC address */
3782 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3784 goto fail;
3785 }
3786 memcpy(pReqMsg->ap[i].bssid, nla_data(
3787 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3788 sizeof(tSirMacAddr));
3789
3790 /* Parse and fetch low RSSI */
3791 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3793 goto fail;
3794 }
3795 pReqMsg->ap[i].low = nla_get_s32(
3796 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3797 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3798
3799 /* Parse and fetch high RSSI */
3800 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3802 goto fail;
3803 }
3804 pReqMsg->ap[i].high = nla_get_s32(
3805 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3806 hddLog(VOS_TRACE_LEVEL_INFO,
3807 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3808
3809 /* Parse and fetch channel */
3810 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3812 goto fail;
3813 }
3814 pReqMsg->ap[i].channel = nla_get_u32(
3815 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3816 hddLog(VOS_TRACE_LEVEL_INFO,
3817 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3818 i++;
3819 }
3820
3821 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3822 if (!HAL_STATUS_SUCCESS(status)) {
3823 hddLog(VOS_TRACE_LEVEL_ERROR,
3824 FL("sme_SetSignificantChange failed(err=%d)"), status);
3825 vos_mem_free(pReqMsg);
3826 return -EINVAL;
3827 }
Dino Myclee8843b32014-07-04 14:21:45 +05303828 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303829 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303830 return 0;
3831
3832fail:
3833 vos_mem_free(pReqMsg);
3834 return -EINVAL;
3835}
3836
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303837static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3838 struct wireless_dev *wdev,
3839 const void *data, int dataLen)
3840{
3841 int ret = 0;
3842
3843 vos_ssr_protect(__func__);
3844 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3845 dataLen);
3846 vos_ssr_unprotect(__func__);
3847
3848 return ret;
3849}
3850
3851static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303852 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303853 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303854{
3855 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3856 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3857 tANI_U8 numChannels = 0;
3858 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3859 tANI_U32 requestId;
3860 tWifiBand wifiBand;
3861 eHalStatus status;
3862 struct sk_buff *replySkb;
3863 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303864 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303865
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303866 ENTER();
3867
Dino Mycle6fb96c12014-06-10 11:52:40 +05303868 status = wlan_hdd_validate_context(pHddCtx);
3869 if (0 != status)
3870 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303871 return -EINVAL;
3872 }
Dino Myclee8843b32014-07-04 14:21:45 +05303873 /* check the EXTScan Capability */
3874 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3875 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3876 {
3877 hddLog(VOS_TRACE_LEVEL_ERROR,
3878 FL("EXTScan not enabled/supported by Firmware"));
3879 return -EINVAL;
3880 }
3881
Dino Mycle6fb96c12014-06-10 11:52:40 +05303882 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3883 data, dataLen,
3884 wlan_hdd_extscan_config_policy)) {
3885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3886 return -EINVAL;
3887 }
3888
3889 /* Parse and fetch request Id */
3890 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3892 return -EINVAL;
3893 }
3894 requestId = nla_get_u32(
3895 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3896 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3897
3898 /* Parse and fetch wifi band */
3899 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3900 {
3901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3902 return -EINVAL;
3903 }
3904 wifiBand = nla_get_u32(
3905 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3906 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3907
3908 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3909 wifiBand, ChannelList,
3910 &numChannels);
3911 if (eHAL_STATUS_SUCCESS != status) {
3912 hddLog(VOS_TRACE_LEVEL_ERROR,
3913 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3914 return -EINVAL;
3915 }
3916 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3917 for (i = 0; i < numChannels; i++)
3918 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3919
3920 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3921 sizeof(u32) * numChannels +
3922 NLMSG_HDRLEN);
3923
3924 if (!replySkb) {
3925 hddLog(VOS_TRACE_LEVEL_ERROR,
3926 FL("valid channels: buffer alloc fail"));
3927 return -EINVAL;
3928 }
3929 if (nla_put_u32(replySkb,
3930 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3931 numChannels) ||
3932 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3933 sizeof(u32) * numChannels, ChannelList)) {
3934
3935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3936 kfree_skb(replySkb);
3937 return -EINVAL;
3938 }
3939
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303940 ret = cfg80211_vendor_cmd_reply(replySkb);
3941
3942 EXIT();
3943 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303944}
3945
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303946static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3947 struct wireless_dev *wdev,
3948 const void *data, int dataLen)
3949{
3950 int ret = 0;
3951
3952 vos_ssr_protect(__func__);
3953 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3954 dataLen);
3955 vos_ssr_unprotect(__func__);
3956
3957 return ret;
3958}
3959
3960static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303961 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303962 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303963{
Dino Myclee8843b32014-07-04 14:21:45 +05303964 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303965 struct net_device *dev = wdev->netdev;
3966 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3967 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3968 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3969 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3970 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3971 struct nlattr *buckets;
3972 struct nlattr *channels;
3973 int rem1;
3974 int rem2;
3975 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303976 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303978 ENTER();
3979
Dino Mycle6fb96c12014-06-10 11:52:40 +05303980 status = wlan_hdd_validate_context(pHddCtx);
3981 if (0 != status)
3982 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303983 return -EINVAL;
3984 }
Dino Myclee8843b32014-07-04 14:21:45 +05303985 /* check the EXTScan Capability */
3986 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3987 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3988 {
3989 hddLog(VOS_TRACE_LEVEL_ERROR,
3990 FL("EXTScan not enabled/supported by Firmware"));
3991 return -EINVAL;
3992 }
3993
Dino Mycle6fb96c12014-06-10 11:52:40 +05303994 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3995 data, dataLen,
3996 wlan_hdd_extscan_config_policy)) {
3997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3998 return -EINVAL;
3999 }
4000
4001 /* Parse and fetch request Id */
4002 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4004 return -EINVAL;
4005 }
4006
Dino Myclee8843b32014-07-04 14:21:45 +05304007 pReqMsg = (tpSirEXTScanStartReqParams)
4008 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304009 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4011 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304012 }
4013
4014 pReqMsg->requestId = nla_get_u32(
4015 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4016 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4017
4018 pReqMsg->sessionId = pAdapter->sessionId;
4019 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4020
4021 /* Parse and fetch base period */
4022 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
4023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4024 goto fail;
4025 }
4026 pReqMsg->basePeriod = nla_get_u32(
4027 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
4028 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4029 pReqMsg->basePeriod);
4030
4031 /* Parse and fetch max AP per scan */
4032 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
4033 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4034 goto fail;
4035 }
4036 pReqMsg->maxAPperScan = nla_get_u32(
4037 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
4038 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4039 pReqMsg->maxAPperScan);
4040
4041 /* Parse and fetch report threshold */
4042 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
4043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4044 goto fail;
4045 }
4046 pReqMsg->reportThreshold = nla_get_u8(
4047 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
4048 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
4049 pReqMsg->reportThreshold);
4050
4051 /* Parse and fetch number of buckets */
4052 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
4053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4054 goto fail;
4055 }
4056 pReqMsg->numBuckets = nla_get_u8(
4057 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
4058 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4059 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4060 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4061 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4062 }
4063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4064 pReqMsg->numBuckets);
4065 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4067 goto fail;
4068 }
4069
4070 nla_for_each_nested(buckets,
4071 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4072 if(nla_parse(bucket,
4073 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4074 nla_data(buckets), nla_len(buckets), NULL)) { //policy
4075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4076 goto fail;
4077 }
4078
4079 /* Parse and fetch bucket spec */
4080 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
4082 goto fail;
4083 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304084
4085 pReqMsg->buckets[index].bucket = nla_get_u8(
4086 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4087
4088 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
4089 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304090
4091 /* Parse and fetch wifi band */
4092 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4094 goto fail;
4095 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304096 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304097 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4098 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304099 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304100
4101 /* Parse and fetch period */
4102 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
4104 goto fail;
4105 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304106 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304107 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4108 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304109 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304110
4111 /* Parse and fetch report events */
4112 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
4114 goto fail;
4115 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304116 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4118 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304119 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304120
4121 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304122 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
4123 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
4125 goto fail;
4126 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304127 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304128 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4129 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304130 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304131
4132 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
4134 goto fail;
4135 }
4136
4137 j = 0;
4138 nla_for_each_nested(channels,
4139 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4140 if(nla_parse(channel,
4141 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4142 nla_data(channels), nla_len(channels),
4143 NULL)) { //wlan_hdd_extscan_config_policy here
4144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4145 goto fail;
4146 }
4147
4148 /* Parse and fetch channel */
4149 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4151 goto fail;
4152 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304153 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304154 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4155 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304156 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304157
4158 /* Parse and fetch dwell time */
4159 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4161 goto fail;
4162 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304163 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304164 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4165 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304166 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304167
4168 /* Parse and fetch channel spec passive */
4169 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4170 hddLog(VOS_TRACE_LEVEL_ERROR,
4171 FL("attr channel spec passive failed"));
4172 goto fail;
4173 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304174 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304175 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304177 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304178 j++;
4179 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304180 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304181 }
4182 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4183 if (!HAL_STATUS_SUCCESS(status)) {
4184 hddLog(VOS_TRACE_LEVEL_ERROR,
4185 FL("sme_EXTScanStart failed(err=%d)"), status);
4186 vos_mem_free(pReqMsg);
4187 return -EINVAL;
4188 }
4189
Dino Myclee8843b32014-07-04 14:21:45 +05304190 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304191 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304192 return 0;
4193
4194fail:
4195 vos_mem_free(pReqMsg);
4196 return -EINVAL;
4197}
4198
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304199static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4200 struct wireless_dev *wdev,
4201 const void *data, int dataLen)
4202{
4203 int ret = 0;
4204
4205 vos_ssr_protect(__func__);
4206 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4207 vos_ssr_unprotect(__func__);
4208
4209 return ret;
4210}
4211
4212static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304214 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215{
Dino Myclee8843b32014-07-04 14:21:45 +05304216 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304217 struct net_device *dev = wdev->netdev;
4218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4219 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4220 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4221 eHalStatus status;
4222
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304223 ENTER();
4224
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 status = wlan_hdd_validate_context(pHddCtx);
4226 if (0 != status)
4227 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304228 return -EINVAL;
4229 }
Dino Myclee8843b32014-07-04 14:21:45 +05304230 /* check the EXTScan Capability */
4231 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4232 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4233 {
4234 hddLog(VOS_TRACE_LEVEL_ERROR,
4235 FL("EXTScan not enabled/supported by Firmware"));
4236 return -EINVAL;
4237 }
4238
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4240 data, dataLen,
4241 wlan_hdd_extscan_config_policy)) {
4242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4243 return -EINVAL;
4244 }
4245
4246 /* Parse and fetch request Id */
4247 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4249 return -EINVAL;
4250 }
4251
Dino Myclee8843b32014-07-04 14:21:45 +05304252 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304254 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255
Dino Myclee8843b32014-07-04 14:21:45 +05304256 reqMsg.sessionId = pAdapter->sessionId;
4257 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258
Dino Myclee8843b32014-07-04 14:21:45 +05304259 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304260 if (!HAL_STATUS_SUCCESS(status)) {
4261 hddLog(VOS_TRACE_LEVEL_ERROR,
4262 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304263 return -EINVAL;
4264 }
4265
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304266 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304267 return 0;
4268}
4269
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304270static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4271 struct wireless_dev *wdev,
4272 const void *data, int dataLen)
4273{
4274 int ret = 0;
4275
4276 vos_ssr_protect(__func__);
4277 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4278 vos_ssr_unprotect(__func__);
4279
4280 return ret;
4281}
4282
4283static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304284 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304285 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304286{
Dino Myclee8843b32014-07-04 14:21:45 +05304287 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288 struct net_device *dev = wdev->netdev;
4289 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4290 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4291 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4292 eHalStatus status;
4293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304294 ENTER();
4295
Dino Mycle6fb96c12014-06-10 11:52:40 +05304296 status = wlan_hdd_validate_context(pHddCtx);
4297 if (0 != status)
4298 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299 return -EINVAL;
4300 }
Dino Myclee8843b32014-07-04 14:21:45 +05304301 /* check the EXTScan Capability */
4302 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4303 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4304 {
4305 hddLog(VOS_TRACE_LEVEL_ERROR,
4306 FL("EXTScan not enabled/supported by Firmware"));
4307 return -EINVAL;
4308 }
4309
Dino Mycle6fb96c12014-06-10 11:52:40 +05304310 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4311 data, dataLen,
4312 wlan_hdd_extscan_config_policy)) {
4313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4314 return -EINVAL;
4315 }
4316
4317 /* Parse and fetch request Id */
4318 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4320 return -EINVAL;
4321 }
4322
Dino Myclee8843b32014-07-04 14:21:45 +05304323 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304324 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304325 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304326
Dino Myclee8843b32014-07-04 14:21:45 +05304327 reqMsg.sessionId = pAdapter->sessionId;
4328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304329
Dino Myclee8843b32014-07-04 14:21:45 +05304330 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304331 if (!HAL_STATUS_SUCCESS(status)) {
4332 hddLog(VOS_TRACE_LEVEL_ERROR,
4333 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304334 return -EINVAL;
4335 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304336 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304337 return 0;
4338}
4339
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304340static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4341 struct wireless_dev *wdev,
4342 const void *data, int dataLen)
4343{
4344 int ret = 0;
4345
4346 vos_ssr_protect(__func__);
4347 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4348 vos_ssr_unprotect(__func__);
4349
4350 return ret;
4351}
4352
4353static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304354 struct wiphy *wiphy,
4355 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304356 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304357{
Dino Myclee8843b32014-07-04 14:21:45 +05304358 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304359 struct net_device *dev = wdev->netdev;
4360 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4361 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4362 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4363 eHalStatus status;
4364
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304365 ENTER();
4366
Dino Mycle6fb96c12014-06-10 11:52:40 +05304367 status = wlan_hdd_validate_context(pHddCtx);
4368 if (0 != status)
4369 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304370 return -EINVAL;
4371 }
Dino Myclee8843b32014-07-04 14:21:45 +05304372 /* check the EXTScan Capability */
4373 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4374 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4375 {
4376 hddLog(VOS_TRACE_LEVEL_ERROR,
4377 FL("EXTScan not enabled/supported by Firmware"));
4378 return -EINVAL;
4379 }
4380
Dino Mycle6fb96c12014-06-10 11:52:40 +05304381 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4382 data, dataLen,
4383 wlan_hdd_extscan_config_policy)) {
4384 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4385 return -EINVAL;
4386 }
4387
4388 /* Parse and fetch request Id */
4389 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4391 return -EINVAL;
4392 }
4393
Dino Mycle6fb96c12014-06-10 11:52:40 +05304394
Dino Myclee8843b32014-07-04 14:21:45 +05304395 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304396 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304397 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304398
Dino Myclee8843b32014-07-04 14:21:45 +05304399 reqMsg.sessionId = pAdapter->sessionId;
4400 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401
Dino Myclee8843b32014-07-04 14:21:45 +05304402 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304403 if (!HAL_STATUS_SUCCESS(status)) {
4404 hddLog(VOS_TRACE_LEVEL_ERROR,
4405 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304406 return -EINVAL;
4407 }
4408
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304409 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410 return 0;
4411}
4412
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304413static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4414 struct wiphy *wiphy,
4415 struct wireless_dev *wdev,
4416 const void *data, int dataLen)
4417{
4418 int ret = 0;
4419
4420 vos_ssr_protect(__func__);
4421 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4422 wdev, data,
4423 dataLen);
4424 vos_ssr_unprotect(__func__);
4425
4426 return ret;
4427}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304428#endif /* WLAN_FEATURE_EXTSCAN */
4429
Atul Mittal115287b2014-07-08 13:26:33 +05304430/*EXT TDLS*/
4431static const struct nla_policy
4432wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4433{
4434 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4435 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4436 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4437 {.type = NLA_S32 },
4438 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4439 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4440
4441};
4442
4443static const struct nla_policy
4444wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4445{
4446 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4447
4448};
4449
4450static const struct nla_policy
4451wlan_hdd_tdls_config_state_change_policy[
4452 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4453{
4454 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4455 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4456 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304457 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4458 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4459 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304460
4461};
4462
4463static const struct nla_policy
4464wlan_hdd_tdls_config_get_status_policy[
4465 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4466{
4467 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4468 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4469 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304470 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4471 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4472 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304473
4474};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304475
4476static const struct nla_policy
4477wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4478{
4479 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4480};
4481
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304482static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304483 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304484 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304485 int data_len)
4486{
4487
4488 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4489 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4490
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304491 ENTER();
4492
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304493 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304494 return -EINVAL;
4495 }
4496 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4498 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304499 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304500 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4502 return -ENOTSUPP;
4503 }
4504
4505 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4506 data, data_len, wlan_hdd_mac_config)) {
4507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4508 return -EINVAL;
4509 }
4510
4511 /* Parse and fetch mac address */
4512 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4514 return -EINVAL;
4515 }
4516
4517 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4518 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4519 VOS_MAC_ADDR_LAST_3_BYTES);
4520
Siddharth Bhal76972212014-10-15 16:22:51 +05304521 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4522
4523 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304524 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4525 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304526 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4527 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4528 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4529 {
4530 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4531 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4532 VOS_MAC_ADDRESS_LEN);
4533 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304534 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304535
Siddharth Bhal76972212014-10-15 16:22:51 +05304536 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4537 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304538 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4539 }
4540
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304541 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304542 return 0;
4543}
4544
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304545static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4546 struct wireless_dev *wdev,
4547 const void *data,
4548 int data_len)
4549{
4550 int ret = 0;
4551
4552 vos_ssr_protect(__func__);
4553 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4554 vos_ssr_unprotect(__func__);
4555
4556 return ret;
4557}
4558
4559static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304560 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304561 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304562 int data_len)
4563{
4564 u8 peer[6] = {0};
4565 struct net_device *dev = wdev->netdev;
4566 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4567 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4568 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4569 eHalStatus ret;
4570 tANI_S32 state;
4571 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304572 tANI_S32 global_operating_class = 0;
4573 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304574 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304575 int retVal;
4576
4577 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304578
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304579 if (!pAdapter) {
4580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4581 return -EINVAL;
4582 }
4583
Atul Mittal115287b2014-07-08 13:26:33 +05304584 ret = wlan_hdd_validate_context(pHddCtx);
4585 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304586 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304587 return -EINVAL;
4588 }
4589 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304591 return -ENOTSUPP;
4592 }
4593 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4594 data, data_len,
4595 wlan_hdd_tdls_config_get_status_policy)) {
4596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4597 return -EINVAL;
4598 }
4599
4600 /* Parse and fetch mac address */
4601 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4602 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4603 return -EINVAL;
4604 }
4605
4606 memcpy(peer, nla_data(
4607 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4608 sizeof(peer));
4609 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4610
4611 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4612
4613 if (0 != ret) {
4614 hddLog(VOS_TRACE_LEVEL_ERROR,
4615 FL("get status Failed"));
4616 return -EINVAL;
4617 }
4618 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304619 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304620 NLMSG_HDRLEN);
4621
4622 if (!skb) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR,
4624 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4625 return -EINVAL;
4626 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304627 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 +05304628 reason,
4629 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304630 global_operating_class,
4631 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304632 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304633 if (nla_put_s32(skb,
4634 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4635 state) ||
4636 nla_put_s32(skb,
4637 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4638 reason) ||
4639 nla_put_s32(skb,
4640 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4641 global_operating_class) ||
4642 nla_put_s32(skb,
4643 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4644 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304645
4646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4647 goto nla_put_failure;
4648 }
4649
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304650 retVal = cfg80211_vendor_cmd_reply(skb);
4651 EXIT();
4652 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304653
4654nla_put_failure:
4655 kfree_skb(skb);
4656 return -EINVAL;
4657}
4658
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304659static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4660 struct wireless_dev *wdev,
4661 const void *data,
4662 int data_len)
4663{
4664 int ret = 0;
4665
4666 vos_ssr_protect(__func__);
4667 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4668 vos_ssr_unprotect(__func__);
4669
4670 return ret;
4671}
4672
Atul Mittal115287b2014-07-08 13:26:33 +05304673static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4674 tANI_S32 state,
4675 tANI_S32 reason,
4676 void *ctx)
4677{
4678 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304679 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304680 tANI_S32 global_operating_class = 0;
4681 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304682 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304683
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304684 ENTER();
4685
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304686 if (!pAdapter) {
4687 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4688 return -EINVAL;
4689 }
4690
4691 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304692 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304694 return -EINVAL;
4695 }
4696
4697 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304699 return -ENOTSUPP;
4700 }
4701 skb = cfg80211_vendor_event_alloc(
4702 pHddCtx->wiphy,
4703 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4704 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4705 GFP_KERNEL);
4706
4707 if (!skb) {
4708 hddLog(VOS_TRACE_LEVEL_ERROR,
4709 FL("cfg80211_vendor_event_alloc failed"));
4710 return -EINVAL;
4711 }
4712 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304713 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4714 reason,
4715 state,
4716 global_operating_class,
4717 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304718 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4719 MAC_ADDR_ARRAY(mac));
4720
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304721 if (nla_put(skb,
4722 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4723 VOS_MAC_ADDR_SIZE, mac) ||
4724 nla_put_s32(skb,
4725 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4726 state) ||
4727 nla_put_s32(skb,
4728 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4729 reason) ||
4730 nla_put_s32(skb,
4731 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4732 channel) ||
4733 nla_put_s32(skb,
4734 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4735 global_operating_class)
4736 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4738 goto nla_put_failure;
4739 }
4740
4741 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304742 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304743 return (0);
4744
4745nla_put_failure:
4746 kfree_skb(skb);
4747 return -EINVAL;
4748}
4749
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304750static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304751 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304752 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304753 int data_len)
4754{
4755 u8 peer[6] = {0};
4756 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304757 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4758 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4759 eHalStatus status;
4760 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304761 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304762 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304763
4764 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304765
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304766 if (!dev) {
4767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4768 return -EINVAL;
4769 }
4770
4771 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4772 if (!pAdapter) {
4773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4774 return -EINVAL;
4775 }
4776
Atul Mittal115287b2014-07-08 13:26:33 +05304777 status = wlan_hdd_validate_context(pHddCtx);
4778 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304780 return -EINVAL;
4781 }
4782 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304784 return -ENOTSUPP;
4785 }
4786 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4787 data, data_len,
4788 wlan_hdd_tdls_config_enable_policy)) {
4789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4790 return -EINVAL;
4791 }
4792
4793 /* Parse and fetch mac address */
4794 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4796 return -EINVAL;
4797 }
4798
4799 memcpy(peer, nla_data(
4800 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4801 sizeof(peer));
4802 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4803
4804 /* Parse and fetch channel */
4805 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4807 return -EINVAL;
4808 }
4809 pReqMsg.channel = nla_get_s32(
4810 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4811 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4812
4813 /* Parse and fetch global operating class */
4814 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4816 return -EINVAL;
4817 }
4818 pReqMsg.global_operating_class = nla_get_s32(
4819 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4821 pReqMsg.global_operating_class);
4822
4823 /* Parse and fetch latency ms */
4824 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4826 return -EINVAL;
4827 }
4828 pReqMsg.max_latency_ms = nla_get_s32(
4829 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4830 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4831 pReqMsg.max_latency_ms);
4832
4833 /* Parse and fetch required bandwidth kbps */
4834 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4836 return -EINVAL;
4837 }
4838
4839 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4840 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4841 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4842 pReqMsg.min_bandwidth_kbps);
4843
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304844 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304845 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304846 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304847 wlan_hdd_cfg80211_exttdls_callback);
4848
4849 EXIT();
4850 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304851}
4852
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304853static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4854 struct wireless_dev *wdev,
4855 const void *data,
4856 int data_len)
4857{
4858 int ret = 0;
4859
4860 vos_ssr_protect(__func__);
4861 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4862 vos_ssr_unprotect(__func__);
4863
4864 return ret;
4865}
4866
4867static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304868 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304869 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304870 int data_len)
4871{
4872 u8 peer[6] = {0};
4873 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304874 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4875 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4876 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304877 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304878 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304879
4880 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304881
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304882 if (!dev) {
4883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4884 return -EINVAL;
4885 }
4886
4887 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4888 if (!pAdapter) {
4889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4890 return -EINVAL;
4891 }
4892
Atul Mittal115287b2014-07-08 13:26:33 +05304893 status = wlan_hdd_validate_context(pHddCtx);
4894 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304896 return -EINVAL;
4897 }
4898 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304900 return -ENOTSUPP;
4901 }
4902 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4903 data, data_len,
4904 wlan_hdd_tdls_config_disable_policy)) {
4905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4906 return -EINVAL;
4907 }
4908 /* Parse and fetch mac address */
4909 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4911 return -EINVAL;
4912 }
4913
4914 memcpy(peer, nla_data(
4915 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4916 sizeof(peer));
4917 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4918
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304919 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4920
4921 EXIT();
4922 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304923}
4924
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304925static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4926 struct wireless_dev *wdev,
4927 const void *data,
4928 int data_len)
4929{
4930 int ret = 0;
4931
4932 vos_ssr_protect(__func__);
4933 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4934 vos_ssr_unprotect(__func__);
4935
4936 return ret;
4937}
4938
Dasari Srinivas7875a302014-09-26 17:50:57 +05304939static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304940__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304941 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304942 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304943{
4944 struct net_device *dev = wdev->netdev;
4945 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4946 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4947 struct sk_buff *skb = NULL;
4948 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304949 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304950
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304951 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304952
4953 ret = wlan_hdd_validate_context(pHddCtx);
4954 if (0 != ret)
4955 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304956 return ret;
4957 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304958 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4959 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4960 fset |= WIFI_FEATURE_INFRA;
4961 }
4962
4963 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4964 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4965 fset |= WIFI_FEATURE_INFRA_5G;
4966 }
4967
4968#ifdef WLAN_FEATURE_P2P
4969 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4970 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4971 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4972 fset |= WIFI_FEATURE_P2P;
4973 }
4974#endif
4975
4976 /* Soft-AP is supported currently by default */
4977 fset |= WIFI_FEATURE_SOFT_AP;
4978
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05304979 /* HOTSPOT is a supplicant feature, enable it by default */
4980 fset |= WIFI_FEATURE_HOTSPOT;
4981
Dasari Srinivas7875a302014-09-26 17:50:57 +05304982#ifdef WLAN_FEATURE_EXTSCAN
4983 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4984 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4985 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4986 fset |= WIFI_FEATURE_EXTSCAN;
4987 }
4988#endif
4989
Dasari Srinivas7875a302014-09-26 17:50:57 +05304990 if (sme_IsFeatureSupportedByFW(NAN)) {
4991 hddLog(LOG1, FL("NAN is supported by firmware"));
4992 fset |= WIFI_FEATURE_NAN;
4993 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05304994
4995 /* D2D RTT is not supported currently by default */
4996 if (sme_IsFeatureSupportedByFW(RTT)) {
4997 hddLog(LOG1, FL("RTT is supported by firmware"));
4998 fset |= WIFI_FEATURE_D2AP_RTT;
4999 }
5000
5001#ifdef FEATURE_WLAN_BATCH_SCAN
5002 if (fset & WIFI_FEATURE_EXTSCAN) {
5003 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5004 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5005 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5006 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5007 fset |= WIFI_FEATURE_BATCH_SCAN;
5008 }
5009#endif
5010
5011#ifdef FEATURE_WLAN_SCAN_PNO
5012 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5013 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5014 hddLog(LOG1, FL("PNO is supported by firmware"));
5015 fset |= WIFI_FEATURE_PNO;
5016 }
5017#endif
5018
5019 /* STA+STA is supported currently by default */
5020 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5021
5022#ifdef FEATURE_WLAN_TDLS
5023 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5024 sme_IsFeatureSupportedByFW(TDLS)) {
5025 hddLog(LOG1, FL("TDLS is supported by firmware"));
5026 fset |= WIFI_FEATURE_TDLS;
5027 }
5028
5029 /* TDLS_OFFCHANNEL is not supported currently by default */
5030#endif
5031
5032#ifdef WLAN_AP_STA_CONCURRENCY
5033 /* AP+STA concurrency is supported currently by default */
5034 fset |= WIFI_FEATURE_AP_STA;
5035#endif
5036
5037 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5038 NLMSG_HDRLEN);
5039
5040 if (!skb) {
5041 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5042 return -EINVAL;
5043 }
5044 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5045
5046 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5047 hddLog(LOGE, FL("nla put fail"));
5048 goto nla_put_failure;
5049 }
5050
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305051 ret = cfg80211_vendor_cmd_reply(skb);
5052 EXIT();
5053 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305054
5055nla_put_failure:
5056 kfree_skb(skb);
5057 return -EINVAL;
5058}
5059
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305060static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305061wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5062 struct wireless_dev *wdev,
5063 const void *data, int data_len)
5064{
5065 int ret = 0;
5066
5067 vos_ssr_protect(__func__);
5068 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5069 vos_ssr_unprotect(__func__);
5070
5071 return ret;
5072}
5073
5074static int
5075__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305076 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305077 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305078{
5079 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5080 uint8_t i, feature_sets, max_feature_sets;
5081 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5082 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5084 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305085
5086 ENTER();
5087
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305088 ret = wlan_hdd_validate_context(pHddCtx);
5089 if (0 != ret)
5090 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305091 return ret;
5092 }
5093
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305094 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5095 data, data_len, NULL)) {
5096 hddLog(LOGE, FL("Invalid ATTR"));
5097 return -EINVAL;
5098 }
5099
5100 /* Parse and fetch max feature set */
5101 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5102 hddLog(LOGE, FL("Attr max feature set size failed"));
5103 return -EINVAL;
5104 }
5105 max_feature_sets = nla_get_u32(
5106 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5107 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5108
5109 /* Fill feature combination matrix */
5110 feature_sets = 0;
5111 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
5112 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5113 WIFI_FEATURE_P2P;
5114
5115 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
5116 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5117 WIFI_FEATURE_SOFT_AP;
5118
5119 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
5120 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5121 WIFI_FEATURE_SOFT_AP;
5122
5123 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
5124 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5125 WIFI_FEATURE_SOFT_AP |
5126 WIFI_FEATURE_P2P;
5127
5128 /* Add more feature combinations here */
5129
5130 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5131 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5132 hddLog(LOG1, "Feature set matrix");
5133 for (i = 0; i < feature_sets; i++)
5134 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5135
5136 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5137 sizeof(u32) * feature_sets +
5138 NLMSG_HDRLEN);
5139
5140 if (reply_skb) {
5141 if (nla_put_u32(reply_skb,
5142 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5143 feature_sets) ||
5144 nla_put(reply_skb,
5145 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5146 sizeof(u32) * feature_sets, feature_set_matrix)) {
5147 hddLog(LOGE, FL("nla put fail"));
5148 kfree_skb(reply_skb);
5149 return -EINVAL;
5150 }
5151
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305152 ret = cfg80211_vendor_cmd_reply(reply_skb);
5153 EXIT();
5154 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305155 }
5156 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5157 return -ENOMEM;
5158
5159max_buffer_err:
5160 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
5161 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
5162 return -EINVAL;
5163}
5164
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305165static int
5166wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5167 struct wireless_dev *wdev,
5168 const void *data, int data_len)
5169{
5170 int ret = 0;
5171
5172 vos_ssr_protect(__func__);
5173 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5174 data_len);
5175 vos_ssr_unprotect(__func__);
5176
5177 return ret;
5178}
5179
Agarwal Ashish738843c2014-09-25 12:27:56 +05305180static const struct nla_policy
5181wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5182 +1] =
5183{
5184 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5185};
5186
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305187static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305188 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305189 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305190 int data_len)
5191{
5192 struct net_device *dev = wdev->netdev;
5193 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5194 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5195 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5196 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5197 eHalStatus status;
5198 u32 dfsFlag = 0;
5199
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305200 ENTER();
5201
Agarwal Ashish738843c2014-09-25 12:27:56 +05305202 status = wlan_hdd_validate_context(pHddCtx);
5203 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305204 return -EINVAL;
5205 }
5206 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5207 data, data_len,
5208 wlan_hdd_set_no_dfs_flag_config_policy)) {
5209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5210 return -EINVAL;
5211 }
5212
5213 /* Parse and fetch required bandwidth kbps */
5214 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5216 return -EINVAL;
5217 }
5218
5219 dfsFlag = nla_get_u32(
5220 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5221 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5222 dfsFlag);
5223
5224 pHddCtx->disable_dfs_flag = dfsFlag;
5225
5226 sme_disable_dfs_channel(hHal, dfsFlag);
5227 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305228
5229 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305230 return 0;
5231}
Atul Mittal115287b2014-07-08 13:26:33 +05305232
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305233static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5234 struct wireless_dev *wdev,
5235 const void *data,
5236 int data_len)
5237{
5238 int ret = 0;
5239
5240 vos_ssr_protect(__func__);
5241 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5242 vos_ssr_unprotect(__func__);
5243
5244 return ret;
5245
5246}
5247
Mukul Sharma2a271632014-10-13 14:59:01 +05305248const struct
5249nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5250{
5251 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5252 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5253};
5254
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305255static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305256 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305257{
5258
5259 u8 bssid[6] = {0};
5260 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5261 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5262 eHalStatus status = eHAL_STATUS_SUCCESS;
5263 v_U32_t isFwrRoamEnabled = FALSE;
5264 int ret;
5265
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305266 ENTER();
5267
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305268 ret = wlan_hdd_validate_context(pHddCtx);
5269 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305270 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305271 }
5272
5273 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5274 data, data_len,
5275 qca_wlan_vendor_attr);
5276 if (ret){
5277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5278 return -EINVAL;
5279 }
5280
5281 /* Parse and fetch Enable flag */
5282 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5284 return -EINVAL;
5285 }
5286
5287 isFwrRoamEnabled = nla_get_u32(
5288 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5289
5290 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5291
5292 /* Parse and fetch bssid */
5293 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5294 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5295 return -EINVAL;
5296 }
5297
5298 memcpy(bssid, nla_data(
5299 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5300 sizeof(bssid));
5301 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5302
5303 //Update roaming
5304 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305305 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305306 return status;
5307}
5308
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305309static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5310 struct wireless_dev *wdev, const void *data, int data_len)
5311{
5312 int ret = 0;
5313
5314 vos_ssr_protect(__func__);
5315 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5316 vos_ssr_unprotect(__func__);
5317
5318 return ret;
5319}
5320
Sunil Duttc69bccb2014-05-26 21:30:20 +05305321const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5322{
Mukul Sharma2a271632014-10-13 14:59:01 +05305323 {
5324 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5325 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5326 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5327 WIPHY_VENDOR_CMD_NEED_NETDEV |
5328 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305329 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305330 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305331
5332 {
5333 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5334 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5335 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5336 WIPHY_VENDOR_CMD_NEED_NETDEV |
5337 WIPHY_VENDOR_CMD_NEED_RUNNING,
5338 .doit = wlan_hdd_cfg80211_nan_request
5339 },
5340
Sunil Duttc69bccb2014-05-26 21:30:20 +05305341#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5342 {
5343 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5344 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5345 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5346 WIPHY_VENDOR_CMD_NEED_NETDEV |
5347 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305348 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305349 },
5350
5351 {
5352 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5353 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5354 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5355 WIPHY_VENDOR_CMD_NEED_NETDEV |
5356 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305357 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305358 },
5359
5360 {
5361 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5362 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5363 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5364 WIPHY_VENDOR_CMD_NEED_NETDEV |
5365 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305366 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305367 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305368#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305369#ifdef WLAN_FEATURE_EXTSCAN
5370 {
5371 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5372 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5373 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5374 WIPHY_VENDOR_CMD_NEED_NETDEV |
5375 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305376 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305377 },
5378 {
5379 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5380 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5381 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5382 WIPHY_VENDOR_CMD_NEED_NETDEV |
5383 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305384 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305385 },
5386 {
5387 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5388 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5389 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5390 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305391 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305392 },
5393 {
5394 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5395 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5396 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5397 WIPHY_VENDOR_CMD_NEED_NETDEV |
5398 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305399 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305400 },
5401 {
5402 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5403 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5404 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5405 WIPHY_VENDOR_CMD_NEED_NETDEV |
5406 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305407 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305408 },
5409 {
5410 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5411 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5412 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5413 WIPHY_VENDOR_CMD_NEED_NETDEV |
5414 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305415 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305416 },
5417 {
5418 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5419 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5420 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5421 WIPHY_VENDOR_CMD_NEED_NETDEV |
5422 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305423 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424 },
5425 {
5426 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5427 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5428 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5429 WIPHY_VENDOR_CMD_NEED_NETDEV |
5430 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305431 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305432 },
5433 {
5434 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5435 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5436 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5437 WIPHY_VENDOR_CMD_NEED_NETDEV |
5438 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305439 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305440 },
5441#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305442/*EXT TDLS*/
5443 {
5444 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5445 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5446 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5447 WIPHY_VENDOR_CMD_NEED_NETDEV |
5448 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305449 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305450 },
5451 {
5452 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5453 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5454 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5455 WIPHY_VENDOR_CMD_NEED_NETDEV |
5456 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305457 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305458 },
5459 {
5460 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5461 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5462 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5463 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305464 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305465 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305466 {
5467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5470 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305471 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305472 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305473 {
5474 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5475 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5476 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5477 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305478 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305479 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305480 {
5481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5484 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305485 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305486 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305487 {
5488 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5489 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5490 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5491 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305492 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305493 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305494};
5495
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005496/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305497static const
5498struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005499{
5500#ifdef FEATURE_WLAN_CH_AVOID
5501 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305502 .vendor_id = QCA_NL80211_VENDOR_ID,
5503 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005504 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305505#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5506#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5507 {
5508 /* Index = 1*/
5509 .vendor_id = QCA_NL80211_VENDOR_ID,
5510 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5511 },
5512 {
5513 /* Index = 2*/
5514 .vendor_id = QCA_NL80211_VENDOR_ID,
5515 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5516 },
5517 {
5518 /* Index = 3*/
5519 .vendor_id = QCA_NL80211_VENDOR_ID,
5520 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5521 },
5522 {
5523 /* Index = 4*/
5524 .vendor_id = QCA_NL80211_VENDOR_ID,
5525 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5526 },
5527 {
5528 /* Index = 5*/
5529 .vendor_id = QCA_NL80211_VENDOR_ID,
5530 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5531 },
5532 {
5533 /* Index = 6*/
5534 .vendor_id = QCA_NL80211_VENDOR_ID,
5535 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5536 },
5537#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305538#ifdef WLAN_FEATURE_EXTSCAN
5539 {
5540 .vendor_id = QCA_NL80211_VENDOR_ID,
5541 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5542 },
5543 {
5544 .vendor_id = QCA_NL80211_VENDOR_ID,
5545 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5546 },
5547 {
5548 .vendor_id = QCA_NL80211_VENDOR_ID,
5549 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5550 },
5551 {
5552 .vendor_id = QCA_NL80211_VENDOR_ID,
5553 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5554 },
5555 {
5556 .vendor_id = QCA_NL80211_VENDOR_ID,
5557 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5558 },
5559 {
5560 .vendor_id = QCA_NL80211_VENDOR_ID,
5561 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5562 },
5563 {
5564 .vendor_id = QCA_NL80211_VENDOR_ID,
5565 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5566 },
5567 {
5568 .vendor_id = QCA_NL80211_VENDOR_ID,
5569 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5570 },
5571 {
5572 .vendor_id = QCA_NL80211_VENDOR_ID,
5573 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5574 },
5575 {
5576 .vendor_id = QCA_NL80211_VENDOR_ID,
5577 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5578 },
5579 {
5580 .vendor_id = QCA_NL80211_VENDOR_ID,
5581 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5582 },
5583 {
5584 .vendor_id = QCA_NL80211_VENDOR_ID,
5585 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5586 },
5587 {
5588 .vendor_id = QCA_NL80211_VENDOR_ID,
5589 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5590 },
5591#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305592/*EXT TDLS*/
5593 {
5594 .vendor_id = QCA_NL80211_VENDOR_ID,
5595 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5596 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305597
5598 {
5599 .vendor_id = QCA_NL80211_VENDOR_ID,
5600 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5601 },
5602
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005603};
5604
Jeff Johnson295189b2012-06-20 16:38:30 -07005605/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305606 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305607 * This function is called by hdd_wlan_startup()
5608 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305609 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005610 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305611struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005612{
5613 struct wiphy *wiphy;
5614 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305615 /*
5616 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 */
5618 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5619
5620 if (!wiphy)
5621 {
5622 /* Print error and jump into err label and free the memory */
5623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5624 return NULL;
5625 }
5626
Sunil Duttc69bccb2014-05-26 21:30:20 +05305627
Jeff Johnson295189b2012-06-20 16:38:30 -07005628 return wiphy;
5629}
5630
5631/*
5632 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305633 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005634 * private ioctl to change the band value
5635 */
5636int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5637{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305638 int i, j;
5639 eNVChannelEnabledType channelEnabledState;
5640
Jeff Johnsone7245742012-09-05 17:12:55 -07005641 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305642
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305643 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305645
5646 if (NULL == wiphy->bands[i])
5647 {
5648 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5649 __func__, i);
5650 continue;
5651 }
5652
5653 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5654 {
5655 struct ieee80211_supported_band *band = wiphy->bands[i];
5656
5657 channelEnabledState = vos_nv_getChannelEnabledState(
5658 band->channels[j].hw_value);
5659
5660 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5661 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305662 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305663 continue;
5664 }
5665 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5666 {
5667 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5668 continue;
5669 }
5670
5671 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5672 NV_CHANNEL_INVALID == channelEnabledState)
5673 {
5674 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5675 }
5676 else if (NV_CHANNEL_DFS == channelEnabledState)
5677 {
5678 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5679 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5680 }
5681 else
5682 {
5683 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5684 |IEEE80211_CHAN_RADAR);
5685 }
5686 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 }
5688 return 0;
5689}
5690/*
5691 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305692 * This function is called by hdd_wlan_startup()
5693 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 * This function is used to initialize and register wiphy structure.
5695 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305696int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005697 struct wiphy *wiphy,
5698 hdd_config_t *pCfg
5699 )
5700{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305701 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305702 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5703
Jeff Johnsone7245742012-09-05 17:12:55 -07005704 ENTER();
5705
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 /* Now bind the underlying wlan device with wiphy */
5707 set_wiphy_dev(wiphy, dev);
5708
5709 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005710
Kiet Lam6c583332013-10-14 05:37:09 +05305711#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005712 /* the flag for the other case would be initialzed in
5713 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005714 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305715#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005716
Amar Singhalfddc28c2013-09-05 13:03:40 -07005717 /* This will disable updating of NL channels from passive to
5718 * active if a beacon is received on passive channel. */
5719 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005720
Amar Singhalfddc28c2013-09-05 13:03:40 -07005721
Amar Singhala49cbc52013-10-08 18:37:44 -07005722
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005723#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005724 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5725 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5726 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005727 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305728 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005729#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005730
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005731#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005732 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005733#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005734 || pCfg->isFastRoamIniFeatureEnabled
5735#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005736#ifdef FEATURE_WLAN_ESE
5737 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005738#endif
5739 )
5740 {
5741 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5742 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005743#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005744#ifdef FEATURE_WLAN_TDLS
5745 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5746 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5747#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305748#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305749 if (pCfg->configPNOScanSupport)
5750 {
5751 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5752 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5753 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5754 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5755 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305756#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005757
Amar Singhalfddc28c2013-09-05 13:03:40 -07005758#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005759 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5760 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005761 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005762 driver need to determine what to do with both
5763 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005764
5765 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005766#else
5767 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005768#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005769
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305770 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5771
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305772 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005773
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305774 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5775
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305777 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005778 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005779 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5780 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005781 | BIT(NL80211_IFTYPE_AP);
5782
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305783 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005784 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305785#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5786 if( pCfg->enableMCC )
5787 {
5788 /* Currently, supports up to two channels */
5789 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005790
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305791 if( !pCfg->allowMCCGODiffBI )
5792 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005793
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305794 }
5795 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5796 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005797#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305798 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005799
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 /* Before registering we need to update the ht capabilitied based
5801 * on ini values*/
5802 if( !pCfg->ShortGI20MhzEnable )
5803 {
5804 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5805 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5806 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5807 }
5808
5809 if( !pCfg->ShortGI40MhzEnable )
5810 {
5811 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5812 }
5813
5814 if( !pCfg->nChannelBondingMode5GHz )
5815 {
5816 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5817 }
5818
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305819 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305820 if (true == hdd_is_5g_supported(pHddCtx))
5821 {
5822 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5823 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305824
5825 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5826 {
5827
5828 if (NULL == wiphy->bands[i])
5829 {
5830 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5831 __func__, i);
5832 continue;
5833 }
5834
5835 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5836 {
5837 struct ieee80211_supported_band *band = wiphy->bands[i];
5838
5839 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5840 {
5841 // Enable social channels for P2P
5842 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5843 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5844 else
5845 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5846 continue;
5847 }
5848 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5849 {
5850 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5851 continue;
5852 }
5853 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005854 }
5855 /*Initialise the supported cipher suite details*/
5856 wiphy->cipher_suites = hdd_cipher_suites;
5857 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5858
5859 /*signal strength in mBm (100*dBm) */
5860 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5861
5862#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305863 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005864#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005865
Sunil Duttc69bccb2014-05-26 21:30:20 +05305866 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5867 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005868 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5869 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5870
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305871 EXIT();
5872 return 0;
5873}
5874
5875/* In this function we are registering wiphy. */
5876int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5877{
5878 ENTER();
5879 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 if (0 > wiphy_register(wiphy))
5881 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305882 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005883 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5884 return -EIO;
5885 }
5886
5887 EXIT();
5888 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889}
Jeff Johnson295189b2012-06-20 16:38:30 -07005890
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305891/* In this function we are updating channel list when,
5892 regulatory domain is FCC and country code is US.
5893 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5894 As per FCC smart phone is not a indoor device.
5895 GO should not opeate on indoor channels */
5896void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5897{
5898 int j;
5899 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5900 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5901 //Default counrtycode from NV at the time of wiphy initialization.
5902 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5903 &defaultCountryCode[0]))
5904 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005905 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305906 }
5907 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5908 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305909 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5910 {
5911 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5912 return;
5913 }
5914 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5915 {
5916 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5917 // Mark UNII -1 band channel as passive
5918 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5919 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5920 }
5921 }
5922}
5923
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305924/* This function registers for all frame which supplicant is interested in */
5925void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005926{
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5928 /* Register for all P2P action, public action etc frames */
5929 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5930
Jeff Johnsone7245742012-09-05 17:12:55 -07005931 ENTER();
5932
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 /* Right now we are registering these frame when driver is getting
5934 initialized. Once we will move to 2.6.37 kernel, in which we have
5935 frame register ops, we will move this code as a part of that */
5936 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305937 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005938 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5939
5940 /* GAS Initial Response */
5941 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5942 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305943
Jeff Johnson295189b2012-06-20 16:38:30 -07005944 /* GAS Comeback Request */
5945 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5946 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5947
5948 /* GAS Comeback Response */
5949 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5950 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5951
5952 /* P2P Public Action */
5953 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305954 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 P2P_PUBLIC_ACTION_FRAME_SIZE );
5956
5957 /* P2P Action */
5958 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5959 (v_U8_t*)P2P_ACTION_FRAME,
5960 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005961
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305962 /* WNM BSS Transition Request frame */
5963 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5964 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5965 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005966
5967 /* WNM-Notification */
5968 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5969 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5970 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005971}
5972
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305973void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005974{
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5976 /* Register for all P2P action, public action etc frames */
5977 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5978
Jeff Johnsone7245742012-09-05 17:12:55 -07005979 ENTER();
5980
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 /* Right now we are registering these frame when driver is getting
5982 initialized. Once we will move to 2.6.37 kernel, in which we have
5983 frame register ops, we will move this code as a part of that */
5984 /* GAS Initial Request */
5985
5986 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5987 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5988
5989 /* GAS Initial Response */
5990 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5991 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305992
Jeff Johnson295189b2012-06-20 16:38:30 -07005993 /* GAS Comeback Request */
5994 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5995 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5996
5997 /* GAS Comeback Response */
5998 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5999 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6000
6001 /* P2P Public Action */
6002 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306003 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 P2P_PUBLIC_ACTION_FRAME_SIZE );
6005
6006 /* P2P Action */
6007 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6008 (v_U8_t*)P2P_ACTION_FRAME,
6009 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006010 /* WNM-Notification */
6011 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6012 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6013 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006014}
6015
6016#ifdef FEATURE_WLAN_WAPI
6017void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
6018 const u8 *mac_addr, u8 *key , int key_Len)
6019{
6020 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6021 tCsrRoamSetKey setKey;
6022 v_BOOL_t isConnected = TRUE;
6023 int status = 0;
6024 v_U32_t roamId= 0xFF;
6025 tANI_U8 *pKeyPtr = NULL;
6026 int n = 0;
6027
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306028 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6029 __func__, hdd_device_modetoString(pAdapter->device_mode),
6030 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006031
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306032 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 setKey.keyId = key_index; // Store Key ID
6034 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6035 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6036 setKey.paeRole = 0 ; // the PAE role
6037 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6038 {
6039 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6040 }
6041 else
6042 {
6043 isConnected = hdd_connIsConnected(pHddStaCtx);
6044 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6045 }
6046 setKey.keyLength = key_Len;
6047 pKeyPtr = setKey.Key;
6048 memcpy( pKeyPtr, key, key_Len);
6049
Arif Hussain6d2a3322013-11-17 19:50:10 -08006050 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 __func__, key_Len);
6052 for (n = 0 ; n < key_Len; n++)
6053 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6054 __func__,n,setKey.Key[n]);
6055
6056 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6057 if ( isConnected )
6058 {
6059 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6060 pAdapter->sessionId, &setKey, &roamId );
6061 }
6062 if ( status != 0 )
6063 {
6064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6065 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6066 __LINE__, status );
6067 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6068 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306069 /* Need to clear any trace of key value in the memory.
6070 * Thus zero out the memory even though it is local
6071 * variable.
6072 */
6073 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006074}
6075#endif /* FEATURE_WLAN_WAPI*/
6076
6077#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306078int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 beacon_data_t **ppBeacon,
6080 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006081#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306082int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006083 beacon_data_t **ppBeacon,
6084 struct cfg80211_beacon_data *params,
6085 int dtim_period)
6086#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087{
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 int size;
6089 beacon_data_t *beacon = NULL;
6090 beacon_data_t *old = NULL;
6091 int head_len,tail_len;
6092
Jeff Johnsone7245742012-09-05 17:12:55 -07006093 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306095 {
6096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6097 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006098 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306099 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006100
6101 old = pAdapter->sessionCtx.ap.beacon;
6102
6103 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306104 {
6105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6106 FL("session(%d) old and new heads points to NULL"),
6107 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006108 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306109 }
6110
6111 if (params->tail && !params->tail_len)
6112 {
6113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6114 FL("tail_len is zero but tail is not NULL"));
6115 return -EINVAL;
6116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006117
Jeff Johnson295189b2012-06-20 16:38:30 -07006118#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6119 /* Kernel 3.0 is not updating dtim_period for set beacon */
6120 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306121 {
6122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6123 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306125 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006126#endif
6127
6128 if(params->head)
6129 head_len = params->head_len;
6130 else
6131 head_len = old->head_len;
6132
6133 if(params->tail || !old)
6134 tail_len = params->tail_len;
6135 else
6136 tail_len = old->tail_len;
6137
6138 size = sizeof(beacon_data_t) + head_len + tail_len;
6139
6140 beacon = kzalloc(size, GFP_KERNEL);
6141
6142 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306143 {
6144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6145 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006146 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306147 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006148
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006149#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 if(params->dtim_period || !old )
6151 beacon->dtim_period = params->dtim_period;
6152 else
6153 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006154#else
6155 if(dtim_period || !old )
6156 beacon->dtim_period = dtim_period;
6157 else
6158 beacon->dtim_period = old->dtim_period;
6159#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306160
Jeff Johnson295189b2012-06-20 16:38:30 -07006161 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6162 beacon->tail = beacon->head + head_len;
6163 beacon->head_len = head_len;
6164 beacon->tail_len = tail_len;
6165
6166 if(params->head) {
6167 memcpy (beacon->head,params->head,beacon->head_len);
6168 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306169 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006170 if(old)
6171 memcpy (beacon->head,old->head,beacon->head_len);
6172 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306173
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 if(params->tail) {
6175 memcpy (beacon->tail,params->tail,beacon->tail_len);
6176 }
6177 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306178 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006179 memcpy (beacon->tail,old->tail,beacon->tail_len);
6180 }
6181
6182 *ppBeacon = beacon;
6183
6184 kfree(old);
6185
6186 return 0;
6187
6188}
Jeff Johnson295189b2012-06-20 16:38:30 -07006189
6190v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
6191{
6192 int left = length;
6193 v_U8_t *ptr = pIes;
6194 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306195
Jeff Johnson295189b2012-06-20 16:38:30 -07006196 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306197 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 elem_id = ptr[0];
6199 elem_len = ptr[1];
6200 left -= 2;
6201 if(elem_len > left)
6202 {
6203 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006204 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 eid,elem_len,left);
6206 return NULL;
6207 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306208 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 {
6210 return ptr;
6211 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306212
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 left -= elem_len;
6214 ptr += (elem_len + 2);
6215 }
6216 return NULL;
6217}
6218
Jeff Johnson295189b2012-06-20 16:38:30 -07006219/* Check if rate is 11g rate or not */
6220static int wlan_hdd_rate_is_11g(u8 rate)
6221{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006222 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 u8 i;
6224 for (i = 0; i < 8; i++)
6225 {
6226 if(rate == gRateArray[i])
6227 return TRUE;
6228 }
6229 return FALSE;
6230}
6231
6232/* Check for 11g rate and set proper 11g only mode */
6233static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6234 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6235{
6236 u8 i, num_rates = pIe[0];
6237
6238 pIe += 1;
6239 for ( i = 0; i < num_rates; i++)
6240 {
6241 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6242 {
6243 /* If rate set have 11g rate than change the mode to 11G */
6244 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6245 if (pIe[i] & BASIC_RATE_MASK)
6246 {
6247 /* If we have 11g rate as basic rate, it means mode
6248 is 11g only mode.
6249 */
6250 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6251 *pCheckRatesfor11g = FALSE;
6252 }
6253 }
6254 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6255 {
6256 *require_ht = TRUE;
6257 }
6258 }
6259 return;
6260}
6261
6262static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6263{
6264 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6265 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6266 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6267 u8 checkRatesfor11g = TRUE;
6268 u8 require_ht = FALSE;
6269 u8 *pIe=NULL;
6270
6271 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6272
6273 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6274 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6275 if (pIe != NULL)
6276 {
6277 pIe += 1;
6278 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6279 &pConfig->SapHw_mode);
6280 }
6281
6282 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6283 WLAN_EID_EXT_SUPP_RATES);
6284 if (pIe != NULL)
6285 {
6286
6287 pIe += 1;
6288 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6289 &pConfig->SapHw_mode);
6290 }
6291
6292 if( pConfig->channel > 14 )
6293 {
6294 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6295 }
6296
6297 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6298 WLAN_EID_HT_CAPABILITY);
6299
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306300 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 {
6302 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6303 if(require_ht)
6304 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6305 }
6306}
6307
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306308static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6309 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6310{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006311 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306312 v_U8_t *pIe = NULL;
6313 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6314
6315 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6316 pBeacon->tail, pBeacon->tail_len);
6317
6318 if (pIe)
6319 {
6320 ielen = pIe[1] + 2;
6321 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6322 {
6323 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6324 }
6325 else
6326 {
6327 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6328 return -EINVAL;
6329 }
6330 *total_ielen += ielen;
6331 }
6332 return 0;
6333}
6334
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006335static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6336 v_U8_t *genie, v_U8_t *total_ielen)
6337{
6338 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6339 int left = pBeacon->tail_len;
6340 v_U8_t *ptr = pBeacon->tail;
6341 v_U8_t elem_id, elem_len;
6342 v_U16_t ielen = 0;
6343
6344 if ( NULL == ptr || 0 == left )
6345 return;
6346
6347 while (left >= 2)
6348 {
6349 elem_id = ptr[0];
6350 elem_len = ptr[1];
6351 left -= 2;
6352 if (elem_len > left)
6353 {
6354 hddLog( VOS_TRACE_LEVEL_ERROR,
6355 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6356 elem_id, elem_len, left);
6357 return;
6358 }
6359 if (IE_EID_VENDOR == elem_id)
6360 {
6361 /* skipping the VSIE's which we don't want to include or
6362 * it will be included by existing code
6363 */
6364 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6365#ifdef WLAN_FEATURE_WFD
6366 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6367#endif
6368 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6369 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6370 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6371 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6372 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6373 {
6374 ielen = ptr[1] + 2;
6375 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6376 {
6377 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6378 *total_ielen += ielen;
6379 }
6380 else
6381 {
6382 hddLog( VOS_TRACE_LEVEL_ERROR,
6383 "IE Length is too big "
6384 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6385 elem_id, elem_len, *total_ielen);
6386 }
6387 }
6388 }
6389
6390 left -= elem_len;
6391 ptr += (elem_len + 2);
6392 }
6393 return;
6394}
6395
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006396#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006397static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6398 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006399#else
6400static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6401 struct cfg80211_beacon_data *params)
6402#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006403{
6404 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306405 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006407 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006408
6409 genie = vos_mem_malloc(MAX_GENIE_LEN);
6410
6411 if(genie == NULL) {
6412
6413 return -ENOMEM;
6414 }
6415
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306416 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6417 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306419 hddLog(LOGE,
6420 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306421 ret = -EINVAL;
6422 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 }
6424
6425#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306426 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6427 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6428 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306429 hddLog(LOGE,
6430 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306431 ret = -EINVAL;
6432 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 }
6434#endif
6435
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306436 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6437 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306439 hddLog(LOGE,
6440 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306441 ret = -EINVAL;
6442 goto done;
6443 }
6444
6445 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6446 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006447 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006449
6450 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6451 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6452 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6453 {
6454 hddLog(LOGE,
6455 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006456 ret = -EINVAL;
6457 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 }
6459
6460 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6461 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6462 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6463 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6464 ==eHAL_STATUS_FAILURE)
6465 {
6466 hddLog(LOGE,
6467 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006468 ret = -EINVAL;
6469 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006470 }
6471
6472 // Added for ProResp IE
6473 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6474 {
6475 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6476 u8 probe_rsp_ie_len[3] = {0};
6477 u8 counter = 0;
6478 /* Check Probe Resp Length if it is greater then 255 then Store
6479 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6480 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6481 Store More then 255 bytes into One Variable.
6482 */
6483 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6484 {
6485 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6486 {
6487 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6488 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6489 }
6490 else
6491 {
6492 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6493 rem_probe_resp_ie_len = 0;
6494 }
6495 }
6496
6497 rem_probe_resp_ie_len = 0;
6498
6499 if (probe_rsp_ie_len[0] > 0)
6500 {
6501 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6502 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6503 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6504 probe_rsp_ie_len[0], NULL,
6505 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6506 {
6507 hddLog(LOGE,
6508 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006509 ret = -EINVAL;
6510 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 }
6512 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6513 }
6514
6515 if (probe_rsp_ie_len[1] > 0)
6516 {
6517 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6518 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6519 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6520 probe_rsp_ie_len[1], NULL,
6521 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6522 {
6523 hddLog(LOGE,
6524 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006525 ret = -EINVAL;
6526 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006527 }
6528 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6529 }
6530
6531 if (probe_rsp_ie_len[2] > 0)
6532 {
6533 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6534 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6535 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6536 probe_rsp_ie_len[2], NULL,
6537 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6538 {
6539 hddLog(LOGE,
6540 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006541 ret = -EINVAL;
6542 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 }
6544 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6545 }
6546
6547 if (probe_rsp_ie_len[1] == 0 )
6548 {
6549 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6550 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6551 eANI_BOOLEAN_FALSE) )
6552 {
6553 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006554 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 }
6556 }
6557
6558 if (probe_rsp_ie_len[2] == 0 )
6559 {
6560 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6561 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6562 eANI_BOOLEAN_FALSE) )
6563 {
6564 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006565 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 }
6567 }
6568
6569 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6570 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6571 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6572 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6573 == eHAL_STATUS_FAILURE)
6574 {
6575 hddLog(LOGE,
6576 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006577 ret = -EINVAL;
6578 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 }
6580 }
6581 else
6582 {
6583 // Reset WNI_CFG_PROBE_RSP Flags
6584 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6585
6586 hddLog(VOS_TRACE_LEVEL_INFO,
6587 "%s: No Probe Response IE received in set beacon",
6588 __func__);
6589 }
6590
6591 // Added for AssocResp IE
6592 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6593 {
6594 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6595 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6596 params->assocresp_ies_len, NULL,
6597 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6598 {
6599 hddLog(LOGE,
6600 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006601 ret = -EINVAL;
6602 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 }
6604
6605 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6606 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6607 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6608 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6609 == eHAL_STATUS_FAILURE)
6610 {
6611 hddLog(LOGE,
6612 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006613 ret = -EINVAL;
6614 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 }
6616 }
6617 else
6618 {
6619 hddLog(VOS_TRACE_LEVEL_INFO,
6620 "%s: No Assoc Response IE received in set beacon",
6621 __func__);
6622
6623 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6624 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6625 eANI_BOOLEAN_FALSE) )
6626 {
6627 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006628 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 }
6630 }
6631
Jeff Johnsone7245742012-09-05 17:12:55 -07006632done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006633 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306634 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006635}
Jeff Johnson295189b2012-06-20 16:38:30 -07006636
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306637/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006638 * FUNCTION: wlan_hdd_validate_operation_channel
6639 * called by wlan_hdd_cfg80211_start_bss() and
6640 * wlan_hdd_cfg80211_set_channel()
6641 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306642 * channel list.
6643 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006644VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006645{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306646
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 v_U32_t num_ch = 0;
6648 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6649 u32 indx = 0;
6650 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306651 v_U8_t fValidChannel = FALSE, count = 0;
6652 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306653
Jeff Johnson295189b2012-06-20 16:38:30 -07006654 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6655
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306656 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306658 /* Validate the channel */
6659 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306661 if ( channel == rfChannels[count].channelNum )
6662 {
6663 fValidChannel = TRUE;
6664 break;
6665 }
6666 }
6667 if (fValidChannel != TRUE)
6668 {
6669 hddLog(VOS_TRACE_LEVEL_ERROR,
6670 "%s: Invalid Channel [%d]", __func__, channel);
6671 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006672 }
6673 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306674 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006675 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306676 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6677 valid_ch, &num_ch))
6678 {
6679 hddLog(VOS_TRACE_LEVEL_ERROR,
6680 "%s: failed to get valid channel list", __func__);
6681 return VOS_STATUS_E_FAILURE;
6682 }
6683 for (indx = 0; indx < num_ch; indx++)
6684 {
6685 if (channel == valid_ch[indx])
6686 {
6687 break;
6688 }
6689 }
6690
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306691 if (indx >= num_ch)
6692 {
6693 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6694 {
6695 eCsrBand band;
6696 unsigned int freq;
6697
6698 sme_GetFreqBand(hHal, &band);
6699
6700 if (eCSR_BAND_5G == band)
6701 {
6702#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6703 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6704 {
6705 freq = ieee80211_channel_to_frequency(channel,
6706 IEEE80211_BAND_2GHZ);
6707 }
6708 else
6709 {
6710 freq = ieee80211_channel_to_frequency(channel,
6711 IEEE80211_BAND_5GHZ);
6712 }
6713#else
6714 freq = ieee80211_channel_to_frequency(channel);
6715#endif
6716 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6717 return VOS_STATUS_SUCCESS;
6718 }
6719 }
6720
6721 hddLog(VOS_TRACE_LEVEL_ERROR,
6722 "%s: Invalid Channel [%d]", __func__, channel);
6723 return VOS_STATUS_E_FAILURE;
6724 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006725 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306726
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306728
Jeff Johnson295189b2012-06-20 16:38:30 -07006729}
6730
Viral Modi3a32cc52013-02-08 11:14:52 -08006731/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306732 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006733 * This function is used to set the channel number
6734 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306735static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006736 struct ieee80211_channel *chan,
6737 enum nl80211_channel_type channel_type
6738 )
6739{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306740 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006741 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006742 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006743 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306744 hdd_context_t *pHddCtx;
6745 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006746
6747 ENTER();
6748
6749 if( NULL == dev )
6750 {
6751 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006752 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006753 return -ENODEV;
6754 }
6755 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306756
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306757 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6758 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6759 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006760 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306761 "%s: device_mode = %s (%d) freq = %d", __func__,
6762 hdd_device_modetoString(pAdapter->device_mode),
6763 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306764
6765 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6766 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306767 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006768 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306769 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006770 }
6771
6772 /*
6773 * Do freq to chan conversion
6774 * TODO: for 11a
6775 */
6776
6777 channel = ieee80211_frequency_to_channel(freq);
6778
6779 /* Check freq range */
6780 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6781 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6782 {
6783 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006784 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006785 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6786 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6787 return -EINVAL;
6788 }
6789
6790 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6791
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306792 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6793 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006794 {
6795 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6796 {
6797 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006798 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006799 return -EINVAL;
6800 }
6801 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6802 "%s: set channel to [%d] for device mode =%d",
6803 __func__, channel,pAdapter->device_mode);
6804 }
6805 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006806 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006807 )
6808 {
6809 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6810 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6811 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6812
6813 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6814 {
6815 /* Link is up then return cant set channel*/
6816 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006817 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006818 return -EINVAL;
6819 }
6820
6821 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6822 pHddStaCtx->conn_info.operationChannel = channel;
6823 pRoamProfile->ChannelInfo.ChannelList =
6824 &pHddStaCtx->conn_info.operationChannel;
6825 }
6826 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006827 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006828 )
6829 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306830 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6831 {
6832 if(VOS_STATUS_SUCCESS !=
6833 wlan_hdd_validate_operation_channel(pAdapter,channel))
6834 {
6835 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006836 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306837 return -EINVAL;
6838 }
6839 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6840 }
6841 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006842 {
6843 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6844
6845 /* If auto channel selection is configured as enable/ 1 then ignore
6846 channel set by supplicant
6847 */
6848 if ( cfg_param->apAutoChannelSelection )
6849 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306850 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6851 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006852 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306853 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6854 __func__, hdd_device_modetoString(pAdapter->device_mode),
6855 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006856 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306857 else
6858 {
6859 if(VOS_STATUS_SUCCESS !=
6860 wlan_hdd_validate_operation_channel(pAdapter,channel))
6861 {
6862 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006863 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306864 return -EINVAL;
6865 }
6866 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6867 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006868 }
6869 }
6870 else
6871 {
6872 hddLog(VOS_TRACE_LEVEL_FATAL,
6873 "%s: Invalid device mode failed to set valid channel", __func__);
6874 return -EINVAL;
6875 }
6876 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306877 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006878}
6879
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306880static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6881 struct net_device *dev,
6882 struct ieee80211_channel *chan,
6883 enum nl80211_channel_type channel_type
6884 )
6885{
6886 int ret;
6887
6888 vos_ssr_protect(__func__);
6889 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6890 vos_ssr_unprotect(__func__);
6891
6892 return ret;
6893}
6894
Jeff Johnson295189b2012-06-20 16:38:30 -07006895#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6896static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6897 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006898#else
6899static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6900 struct cfg80211_beacon_data *params,
6901 const u8 *ssid, size_t ssid_len,
6902 enum nl80211_hidden_ssid hidden_ssid)
6903#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006904{
6905 tsap_Config_t *pConfig;
6906 beacon_data_t *pBeacon = NULL;
6907 struct ieee80211_mgmt *pMgmt_frame;
6908 v_U8_t *pIe=NULL;
6909 v_U16_t capab_info;
6910 eCsrAuthType RSNAuthType;
6911 eCsrEncryptionType RSNEncryptType;
6912 eCsrEncryptionType mcRSNEncryptType;
6913 int status = VOS_STATUS_SUCCESS;
6914 tpWLAN_SAPEventCB pSapEventCallback;
6915 hdd_hostapd_state_t *pHostapdState;
6916 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6917 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306918 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306920 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006922 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306923 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006924 v_BOOL_t MFPCapable = VOS_FALSE;
6925 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05306926 v_BOOL_t sapEnable11AC =
6927 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07006928 ENTER();
6929
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306930 iniConfig = pHddCtx->cfg_ini;
6931
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6933
6934 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6935
6936 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6937
6938 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6939
6940 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6941
6942 //channel is already set in the set_channel Call back
6943 //pConfig->channel = pCommitConfig->channel;
6944
6945 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306946 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6948
6949 pConfig->dtim_period = pBeacon->dtim_period;
6950
Arif Hussain6d2a3322013-11-17 19:50:10 -08006951 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 pConfig->dtim_period);
6953
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006954 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006955 {
6956 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306958 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6959 {
6960 tANI_BOOLEAN restartNeeded;
6961 pConfig->ieee80211d = 1;
6962 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6963 sme_setRegInfo(hHal, pConfig->countryCode);
6964 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6965 }
6966 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006968 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006969 pConfig->ieee80211d = 1;
6970 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6971 sme_setRegInfo(hHal, pConfig->countryCode);
6972 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006974 else
6975 {
6976 pConfig->ieee80211d = 0;
6977 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306978 /*
6979 * If auto channel is configured i.e. channel is 0,
6980 * so skip channel validation.
6981 */
6982 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6983 {
6984 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6985 {
6986 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006987 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306988 return -EINVAL;
6989 }
6990 }
6991 else
6992 {
6993 if(1 != pHddCtx->is_dynamic_channel_range_set)
6994 {
6995 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6996 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6997 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6998 }
6999 pHddCtx->is_dynamic_channel_range_set = 0;
7000 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007001 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007002 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 {
7004 pConfig->ieee80211d = 0;
7005 }
7006 pConfig->authType = eSAP_AUTO_SWITCH;
7007
7008 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307009
7010 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7012
7013 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7014
7015 /*Set wps station to configured*/
7016 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7017
7018 if(pIe)
7019 {
7020 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7021 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007022 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 return -EINVAL;
7024 }
7025 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7026 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007027 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 /* Check 15 bit of WPS IE as it contain information for wps state
7029 * WPS state
7030 */
7031 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7032 {
7033 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7034 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7035 {
7036 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7037 }
7038 }
7039 }
7040 else
7041 {
7042 pConfig->wps_state = SAP_WPS_DISABLED;
7043 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307044 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007045
c_hpothufe599e92014-06-16 11:38:55 +05307046 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7047 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7048 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7049 eCSR_ENCRYPT_TYPE_NONE;
7050
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 pConfig->RSNWPAReqIELength = 0;
7052 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307053 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 WLAN_EID_RSN);
7055 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307056 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7058 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7059 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307060 /* The actual processing may eventually be more extensive than
7061 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 * by the app.
7063 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307064 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7066 &RSNEncryptType,
7067 &mcRSNEncryptType,
7068 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007069 &MFPCapable,
7070 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007071 pConfig->pRSNWPAReqIE[1]+2,
7072 pConfig->pRSNWPAReqIE );
7073
7074 if( VOS_STATUS_SUCCESS == status )
7075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307076 /* Now copy over all the security attributes you have
7077 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 * */
7079 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7080 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7081 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7082 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307083 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007084 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7086 }
7087 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307088
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7090 pBeacon->tail, pBeacon->tail_len);
7091
7092 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7093 {
7094 if (pConfig->pRSNWPAReqIE)
7095 {
7096 /*Mixed mode WPA/WPA2*/
7097 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7098 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7099 }
7100 else
7101 {
7102 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7103 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7104 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307105 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7107 &RSNEncryptType,
7108 &mcRSNEncryptType,
7109 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007110 &MFPCapable,
7111 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 pConfig->pRSNWPAReqIE[1]+2,
7113 pConfig->pRSNWPAReqIE );
7114
7115 if( VOS_STATUS_SUCCESS == status )
7116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307117 /* Now copy over all the security attributes you have
7118 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 * */
7120 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7121 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7122 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7123 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307124 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007125 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007126 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7127 }
7128 }
7129 }
7130
Jeff Johnson4416a782013-03-25 14:17:50 -07007131 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7132 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7133 return -EINVAL;
7134 }
7135
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7137
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007138#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 if (params->ssid != NULL)
7140 {
7141 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7142 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7143 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7144 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7145 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007146#else
7147 if (ssid != NULL)
7148 {
7149 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7150 pConfig->SSIDinfo.ssid.length = ssid_len;
7151 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7152 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7153 }
7154#endif
7155
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307156 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007157 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307158
Jeff Johnson295189b2012-06-20 16:38:30 -07007159 /* default value */
7160 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7161 pConfig->num_accept_mac = 0;
7162 pConfig->num_deny_mac = 0;
7163
7164 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7165 pBeacon->tail, pBeacon->tail_len);
7166
7167 /* pIe for black list is following form:
7168 type : 1 byte
7169 length : 1 byte
7170 OUI : 4 bytes
7171 acl type : 1 byte
7172 no of mac addr in black list: 1 byte
7173 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307174 */
7175 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 {
7177 pConfig->SapMacaddr_acl = pIe[6];
7178 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007179 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007180 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307181 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7182 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007183 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7184 for (i = 0; i < pConfig->num_deny_mac; i++)
7185 {
7186 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7187 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307188 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007189 }
7190 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7191 pBeacon->tail, pBeacon->tail_len);
7192
7193 /* pIe for white list is following form:
7194 type : 1 byte
7195 length : 1 byte
7196 OUI : 4 bytes
7197 acl type : 1 byte
7198 no of mac addr in white list: 1 byte
7199 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307200 */
7201 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007202 {
7203 pConfig->SapMacaddr_acl = pIe[6];
7204 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007205 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307207 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7208 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007209 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7210 for (i = 0; i < pConfig->num_accept_mac; i++)
7211 {
7212 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7213 acl_entry++;
7214 }
7215 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307216
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7218
Jeff Johnsone7245742012-09-05 17:12:55 -07007219#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007220 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307221 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7222 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307223 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7224 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007225 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7226 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307227 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7228 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007229 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307230 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007231 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307232 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007233
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307234 /* If ACS disable and selected channel <= 14
7235 * OR
7236 * ACS enabled and ACS operating band is choosen as 2.4
7237 * AND
7238 * VHT in 2.4G Disabled
7239 * THEN
7240 * Fallback to 11N mode
7241 */
7242 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7243 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307244 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307245 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007246 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307247 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7248 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007249 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7250 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007251 }
7252#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307253
Jeff Johnson295189b2012-06-20 16:38:30 -07007254 // ht_capab is not what the name conveys,this is used for protection bitmap
7255 pConfig->ht_capab =
7256 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7257
7258 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7259 {
7260 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7261 return -EINVAL;
7262 }
7263
7264 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307265 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007266 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7267 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307268 pConfig->obssProtEnabled =
7269 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007270
Chet Lanctot8cecea22014-02-11 19:09:36 -08007271#ifdef WLAN_FEATURE_11W
7272 pConfig->mfpCapable = MFPCapable;
7273 pConfig->mfpRequired = MFPRequired;
7274 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7275 pConfig->mfpCapable, pConfig->mfpRequired);
7276#endif
7277
Arif Hussain6d2a3322013-11-17 19:50:10 -08007278 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007279 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007280 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7281 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7282 (int)pConfig->channel);
7283 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7284 pConfig->SapHw_mode, pConfig->privacy,
7285 pConfig->authType);
7286 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7287 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7288 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7289 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007290
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307291 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 {
7293 //Bss already started. just return.
7294 //TODO Probably it should update some beacon params.
7295 hddLog( LOGE, "Bss Already started...Ignore the request");
7296 EXIT();
7297 return 0;
7298 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307299
Agarwal Ashish51325b52014-06-16 16:50:49 +05307300 if (vos_max_concurrent_connections_reached()) {
7301 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7302 return -EINVAL;
7303 }
7304
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 pConfig->persona = pHostapdAdapter->device_mode;
7306
Peng Xu2446a892014-09-05 17:21:18 +05307307 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7308 if ( NULL != psmeConfig)
7309 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307310 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307311 sme_GetConfigParam(hHal, psmeConfig);
7312 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307313#ifdef WLAN_FEATURE_AP_HT40_24G
7314 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7315 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7316 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7317 {
7318 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7319 sme_UpdateConfig (hHal, psmeConfig);
7320 }
7321#endif
Peng Xu2446a892014-09-05 17:21:18 +05307322 vos_mem_free(psmeConfig);
7323 }
Peng Xuafc34e32014-09-25 13:23:55 +05307324 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307325
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 pSapEventCallback = hdd_hostapd_SAPEventCB;
7327 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7328 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7329 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007330 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 return -EINVAL;
7332 }
7333
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307334 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7336
7337 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307338
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307340 {
7341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007342 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007343 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 VOS_ASSERT(0);
7345 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307346
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307348 /* Initialize WMM configuation */
7349 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307350 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007351
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007352#ifdef WLAN_FEATURE_P2P_DEBUG
7353 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7354 {
7355 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7356 {
7357 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7358 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007359 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007360 }
7361 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7362 {
7363 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7364 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007365 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007366 }
7367 }
7368#endif
7369
Jeff Johnson295189b2012-06-20 16:38:30 -07007370 pHostapdState->bCommit = TRUE;
7371 EXIT();
7372
7373 return 0;
7374}
7375
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007376#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307377static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307378 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 struct beacon_parameters *params)
7380{
7381 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307382 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307383 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007384
7385 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307386
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7388 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7389 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307390 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7391 hdd_device_modetoString(pAdapter->device_mode),
7392 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007393
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307394 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7395 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307396 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007397 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307398 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007399 }
7400
Agarwal Ashish51325b52014-06-16 16:50:49 +05307401 if (vos_max_concurrent_connections_reached()) {
7402 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7403 return -EINVAL;
7404 }
7405
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307406 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007407 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007408 )
7409 {
7410 beacon_data_t *old,*new;
7411
7412 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307413
Jeff Johnson295189b2012-06-20 16:38:30 -07007414 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307415 {
7416 hddLog(VOS_TRACE_LEVEL_WARN,
7417 FL("already beacon info added to session(%d)"),
7418 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007419 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307420 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007421
7422 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7423
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307424 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007425 {
7426 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007427 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007428 return -EINVAL;
7429 }
7430
7431 pAdapter->sessionCtx.ap.beacon = new;
7432
7433 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7434 }
7435
7436 EXIT();
7437 return status;
7438}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307439
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307440static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7441 struct net_device *dev,
7442 struct beacon_parameters *params)
7443{
7444 int ret;
7445
7446 vos_ssr_protect(__func__);
7447 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7448 vos_ssr_unprotect(__func__);
7449
7450 return ret;
7451}
7452
7453static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 struct net_device *dev,
7455 struct beacon_parameters *params)
7456{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307457 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307458 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7459 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307460 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007461
7462 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307463
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307464 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7465 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7466 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7467 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7468 __func__, hdd_device_modetoString(pAdapter->device_mode),
7469 pAdapter->device_mode);
7470
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307471 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7472 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307473 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007474 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307475 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007476 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307477
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307478 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307480 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 {
7482 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307483
Jeff Johnson295189b2012-06-20 16:38:30 -07007484 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307485
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307487 {
7488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7489 FL("session(%d) old and new heads points to NULL"),
7490 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307492 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007493
7494 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7495
7496 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307497 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007498 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007499 return -EINVAL;
7500 }
7501
7502 pAdapter->sessionCtx.ap.beacon = new;
7503
7504 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7505 }
7506
7507 EXIT();
7508 return status;
7509}
7510
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307511static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7512 struct net_device *dev,
7513 struct beacon_parameters *params)
7514{
7515 int ret;
7516
7517 vos_ssr_protect(__func__);
7518 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7519 vos_ssr_unprotect(__func__);
7520
7521 return ret;
7522}
7523
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007524#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7525
7526#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307527static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007528 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007529#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307530static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007531 struct net_device *dev)
7532#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007533{
7534 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007535 hdd_context_t *pHddCtx = NULL;
7536 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307537 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307538 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007539
7540 ENTER();
7541
7542 if (NULL == pAdapter)
7543 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007545 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 return -ENODEV;
7547 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007548
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307549 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7550 TRACE_CODE_HDD_CFG80211_STOP_AP,
7551 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307552 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7553 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307554 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007555 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307556 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007557 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007558
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007559 pScanInfo = &pHddCtx->scan_info;
7560
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307561 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7562 __func__, hdd_device_modetoString(pAdapter->device_mode),
7563 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007564
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307565 ret = wlan_hdd_scan_abort(pAdapter);
7566
Girish Gowli4bf7a632014-06-12 13:42:11 +05307567 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007568 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7570 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307571
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307572 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007573 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7575 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007576
Jeff Johnsone7245742012-09-05 17:12:55 -07007577 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307578 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007579 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307580 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007581 }
7582
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307583 /* Delete all associated STAs before stopping AP/P2P GO */
7584 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307585 hdd_hostapd_stop(dev);
7586
Jeff Johnson295189b2012-06-20 16:38:30 -07007587 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007588 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007589 )
7590 {
7591 beacon_data_t *old;
7592
7593 old = pAdapter->sessionCtx.ap.beacon;
7594
7595 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307596 {
7597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7598 FL("session(%d) beacon data points to NULL"),
7599 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007600 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307601 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007602
Jeff Johnson295189b2012-06-20 16:38:30 -07007603 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007604
7605 mutex_lock(&pHddCtx->sap_lock);
7606 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7607 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007608 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007609 {
7610 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7611
7612 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7613
7614 if (!VOS_IS_STATUS_SUCCESS(status))
7615 {
7616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007617 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007618 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307619 }
7620 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007621 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307622 /* BSS stopped, clear the active sessions for this device mode */
7623 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 }
7625 mutex_unlock(&pHddCtx->sap_lock);
7626
7627 if(status != VOS_STATUS_SUCCESS)
7628 {
7629 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007630 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 return -EINVAL;
7632 }
7633
Jeff Johnson4416a782013-03-25 14:17:50 -07007634 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7636 ==eHAL_STATUS_FAILURE)
7637 {
7638 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007639 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 }
7641
Jeff Johnson4416a782013-03-25 14:17:50 -07007642 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007643 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7644 eANI_BOOLEAN_FALSE) )
7645 {
7646 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007647 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 }
7649
7650 // Reset WNI_CFG_PROBE_RSP Flags
7651 wlan_hdd_reset_prob_rspies(pAdapter);
7652
7653 pAdapter->sessionCtx.ap.beacon = NULL;
7654 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007655#ifdef WLAN_FEATURE_P2P_DEBUG
7656 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7657 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7658 {
7659 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7660 "GO got removed");
7661 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7662 }
7663#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 }
7665 EXIT();
7666 return status;
7667}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007668
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307669#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7670static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7671 struct net_device *dev)
7672{
7673 int ret;
7674
7675 vos_ssr_protect(__func__);
7676 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7677 vos_ssr_unprotect(__func__);
7678
7679 return ret;
7680}
7681#else
7682static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7683 struct net_device *dev)
7684{
7685 int ret;
7686
7687 vos_ssr_protect(__func__);
7688 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7689 vos_ssr_unprotect(__func__);
7690
7691 return ret;
7692}
7693#endif
7694
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007695#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7696
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307697static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307698 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007699 struct cfg80211_ap_settings *params)
7700{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307701 hdd_adapter_t *pAdapter;
7702 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307703 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007704
7705 ENTER();
7706
Girish Gowlib143d7a2015-02-18 19:39:55 +05307707 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007708 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307710 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307711 return -ENODEV;
7712 }
7713
7714 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7715 if (NULL == pAdapter)
7716 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307718 "%s: HDD adapter is Null", __func__);
7719 return -ENODEV;
7720 }
7721
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307722 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7723 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7724 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307725 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7726 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307728 "%s: HDD adapter magic is invalid", __func__);
7729 return -ENODEV;
7730 }
7731
7732 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307733 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307734 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307735 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307736 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307737 }
7738
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307739 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7740 __func__, hdd_device_modetoString(pAdapter->device_mode),
7741 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307742
7743 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007744 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007745 )
7746 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307747 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007748
7749 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307750
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007751 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307752 {
7753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7754 FL("already beacon info added to session(%d)"),
7755 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007756 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307757 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007758
Girish Gowlib143d7a2015-02-18 19:39:55 +05307759#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7760 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7761 &new,
7762 &params->beacon);
7763#else
7764 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7765 &new,
7766 &params->beacon,
7767 params->dtim_period);
7768#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007769
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307770 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007771 {
7772 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307773 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007774 return -EINVAL;
7775 }
7776 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007778 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7779#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7780 params->channel, params->channel_type);
7781#else
7782 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7783#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007784#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007785 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7786 params->ssid_len, params->hidden_ssid);
7787 }
7788
7789 EXIT();
7790 return status;
7791}
7792
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307793static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7794 struct net_device *dev,
7795 struct cfg80211_ap_settings *params)
7796{
7797 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007798
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307799 vos_ssr_protect(__func__);
7800 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7801 vos_ssr_unprotect(__func__);
7802
7803 return ret;
7804}
7805
7806static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007807 struct net_device *dev,
7808 struct cfg80211_beacon_data *params)
7809{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307810 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307811 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307812 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007813
7814 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307815
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7817 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7818 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007820 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307821
7822 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7823 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307824 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007825 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307826 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007827 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007828
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307829 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007830 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307831 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007832 {
7833 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307834
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007835 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307836
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007837 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307838 {
7839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7840 FL("session(%d) beacon data points to NULL"),
7841 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007842 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307843 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007844
7845 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7846
7847 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307848 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007849 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007850 return -EINVAL;
7851 }
7852
7853 pAdapter->sessionCtx.ap.beacon = new;
7854
7855 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7856 }
7857
7858 EXIT();
7859 return status;
7860}
7861
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307862static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7863 struct net_device *dev,
7864 struct cfg80211_beacon_data *params)
7865{
7866 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007867
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307868 vos_ssr_protect(__func__);
7869 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7870 vos_ssr_unprotect(__func__);
7871
7872 return ret;
7873}
7874
7875#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007876
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307877static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 struct net_device *dev,
7879 struct bss_parameters *params)
7880{
7881 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307882 hdd_context_t *pHddCtx;
7883 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007884
7885 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307886
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307887 if (NULL == pAdapter)
7888 {
7889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7890 "%s: HDD adapter is Null", __func__);
7891 return -ENODEV;
7892 }
7893 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307894 ret = wlan_hdd_validate_context(pHddCtx);
7895 if (0 != ret)
7896 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307897 return ret;
7898 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307899 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7900 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7901 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307902 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7903 __func__, hdd_device_modetoString(pAdapter->device_mode),
7904 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007905
7906 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307908 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 {
7910 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7911 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307912 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 {
7914 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307915 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 }
7917
7918 EXIT();
7919 return 0;
7920}
7921
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307922static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7923 struct net_device *dev,
7924 struct bss_parameters *params)
7925{
7926 int ret;
7927
7928 vos_ssr_protect(__func__);
7929 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7930 vos_ssr_unprotect(__func__);
7931
7932 return ret;
7933}
Kiet Lam10841362013-11-01 11:36:50 +05307934/* FUNCTION: wlan_hdd_change_country_code_cd
7935* to wait for contry code completion
7936*/
7937void* wlan_hdd_change_country_code_cb(void *pAdapter)
7938{
7939 hdd_adapter_t *call_back_pAdapter = pAdapter;
7940 complete(&call_back_pAdapter->change_country_code);
7941 return NULL;
7942}
7943
Jeff Johnson295189b2012-06-20 16:38:30 -07007944/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307945 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007946 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7947 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307948int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 struct net_device *ndev,
7950 enum nl80211_iftype type,
7951 u32 *flags,
7952 struct vif_params *params
7953 )
7954{
7955 struct wireless_dev *wdev;
7956 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007957 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007958 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 tCsrRoamProfile *pRoamProfile = NULL;
7960 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307961 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 eMib_dot11DesiredBssType connectedBssType;
7963 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307964 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007965
7966 ENTER();
7967
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307968 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007969 {
7970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7971 "%s: Adapter context is null", __func__);
7972 return VOS_STATUS_E_FAILURE;
7973 }
7974
7975 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7976 if (!pHddCtx)
7977 {
7978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7979 "%s: HDD context is null", __func__);
7980 return VOS_STATUS_E_FAILURE;
7981 }
7982
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307983 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7984 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7985 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307986 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307987 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307989 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007990 }
7991
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307992 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7993 __func__, hdd_device_modetoString(pAdapter->device_mode),
7994 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007995
Agarwal Ashish51325b52014-06-16 16:50:49 +05307996 if (vos_max_concurrent_connections_reached()) {
7997 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7998 return -EINVAL;
7999 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308000 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 wdev = ndev->ieee80211_ptr;
8002
8003#ifdef WLAN_BTAMP_FEATURE
8004 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8005 (NL80211_IFTYPE_ADHOC == type)||
8006 (NL80211_IFTYPE_AP == type)||
8007 (NL80211_IFTYPE_P2P_GO == type))
8008 {
8009 pHddCtx->isAmpAllowed = VOS_FALSE;
8010 // stop AMP traffic
8011 status = WLANBAP_StopAmp();
8012 if(VOS_STATUS_SUCCESS != status )
8013 {
8014 pHddCtx->isAmpAllowed = VOS_TRUE;
8015 hddLog(VOS_TRACE_LEVEL_FATAL,
8016 "%s: Failed to stop AMP", __func__);
8017 return -EINVAL;
8018 }
8019 }
8020#endif //WLAN_BTAMP_FEATURE
8021 /* Reset the current device mode bit mask*/
8022 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8023
8024 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008026 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008027 )
8028 {
8029 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008030 if (!pWextState)
8031 {
8032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8033 "%s: pWextState is null", __func__);
8034 return VOS_STATUS_E_FAILURE;
8035 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 pRoamProfile = &pWextState->roamProfile;
8037 LastBSSType = pRoamProfile->BSSType;
8038
8039 switch (type)
8040 {
8041 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 hddLog(VOS_TRACE_LEVEL_INFO,
8044 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8045 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008046#ifdef WLAN_FEATURE_11AC
8047 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8048 {
8049 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8050 }
8051#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308052 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008053 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008055 //Check for sub-string p2p to confirm its a p2p interface
8056 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308057 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008058 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8059 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8060 }
8061 else
8062 {
8063 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008065 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308067
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 case NL80211_IFTYPE_ADHOC:
8069 hddLog(VOS_TRACE_LEVEL_INFO,
8070 "%s: setting interface Type to ADHOC", __func__);
8071 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8072 pRoamProfile->phyMode =
8073 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008074 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008075 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308076 hdd_set_ibss_ops( pAdapter );
8077 hdd_ibss_init_tx_rx( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 break;
8079
8080 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 {
8083 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8084 "%s: setting interface Type to %s", __func__,
8085 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8086
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008087 //Cancel any remain on channel for GO mode
8088 if (NL80211_IFTYPE_P2P_GO == type)
8089 {
8090 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8091 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008092 if (NL80211_IFTYPE_AP == type)
8093 {
8094 /* As Loading WLAN Driver one interface being created for p2p device
8095 * address. This will take one HW STA and the max number of clients
8096 * that can connect to softAP will be reduced by one. so while changing
8097 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8098 * interface as it is not required in SoftAP mode.
8099 */
8100
8101 // Get P2P Adapter
8102 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8103
8104 if (pP2pAdapter)
8105 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308106 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308107 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008108 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8109 }
8110 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308111 //Disable IMPS & BMPS for SAP/GO
8112 if(VOS_STATUS_E_FAILURE ==
8113 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8114 {
8115 //Fail to Exit BMPS
8116 VOS_ASSERT(0);
8117 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308118
8119 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8120
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308121#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008122
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308123 /* A Mutex Lock is introduced while changing the mode to
8124 * protect the concurrent access for the Adapters by TDLS
8125 * module.
8126 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308127 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308128#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308130 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008131 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8133 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308134#ifdef FEATURE_WLAN_TDLS
8135 mutex_unlock(&pHddCtx->tdls_lock);
8136#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008137 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8138 (pConfig->apRandomBssidEnabled))
8139 {
8140 /* To meet Android requirements create a randomized
8141 MAC address of the form 02:1A:11:Fx:xx:xx */
8142 get_random_bytes(&ndev->dev_addr[3], 3);
8143 ndev->dev_addr[0] = 0x02;
8144 ndev->dev_addr[1] = 0x1A;
8145 ndev->dev_addr[2] = 0x11;
8146 ndev->dev_addr[3] |= 0xF0;
8147 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8148 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008149 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8150 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008151 }
8152
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 hdd_set_ap_ops( pAdapter->dev );
8154
Kiet Lam10841362013-11-01 11:36:50 +05308155 /* This is for only SAP mode where users can
8156 * control country through ini.
8157 * P2P GO follows station country code
8158 * acquired during the STA scanning. */
8159 if((NL80211_IFTYPE_AP == type) &&
8160 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8161 {
8162 int status = 0;
8163 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8164 "%s: setting country code from INI ", __func__);
8165 init_completion(&pAdapter->change_country_code);
8166 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8167 (void *)(tSmeChangeCountryCallback)
8168 wlan_hdd_change_country_code_cb,
8169 pConfig->apCntryCode, pAdapter,
8170 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308171 eSIR_FALSE,
8172 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308173 if (eHAL_STATUS_SUCCESS == status)
8174 {
8175 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308176 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308177 &pAdapter->change_country_code,
8178 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308179 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308180 {
8181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308182 FL("SME Timed out while setting country code %ld"),
8183 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008184
8185 if (pHddCtx->isLogpInProgress)
8186 {
8187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8188 "%s: LOGP in Progress. Ignore!!!", __func__);
8189 return -EAGAIN;
8190 }
Kiet Lam10841362013-11-01 11:36:50 +05308191 }
8192 }
8193 else
8194 {
8195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008196 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308197 return -EINVAL;
8198 }
8199 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008200 status = hdd_init_ap_mode(pAdapter);
8201 if(status != VOS_STATUS_SUCCESS)
8202 {
8203 hddLog(VOS_TRACE_LEVEL_FATAL,
8204 "%s: Error initializing the ap mode", __func__);
8205 return -EINVAL;
8206 }
8207 hdd_set_conparam(1);
8208
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 /*interface type changed update in wiphy structure*/
8210 if(wdev)
8211 {
8212 wdev->iftype = type;
8213 pHddCtx->change_iface = type;
8214 }
8215 else
8216 {
8217 hddLog(VOS_TRACE_LEVEL_ERROR,
8218 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8219 return -EINVAL;
8220 }
8221 goto done;
8222 }
8223
8224 default:
8225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8226 __func__);
8227 return -EOPNOTSUPP;
8228 }
8229 }
8230 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 )
8233 {
8234 switch(type)
8235 {
8236 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008237 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308239
8240 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308241#ifdef FEATURE_WLAN_TDLS
8242
8243 /* A Mutex Lock is introduced while changing the mode to
8244 * protect the concurrent access for the Adapters by TDLS
8245 * module.
8246 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308247 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308248#endif
c_hpothu002231a2015-02-05 14:58:51 +05308249 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008251 //Check for sub-string p2p to confirm its a p2p interface
8252 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008253 {
8254 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8255 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8256 }
8257 else
8258 {
8259 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008261 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 hdd_set_conparam(0);
8263 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8265 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308266#ifdef FEATURE_WLAN_TDLS
8267 mutex_unlock(&pHddCtx->tdls_lock);
8268#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308269 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 if( VOS_STATUS_SUCCESS != status )
8271 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008272 /* In case of JB, for P2P-GO, only change interface will be called,
8273 * This is the right place to enable back bmps_imps()
8274 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308275 if (pHddCtx->hdd_wlan_suspended)
8276 {
8277 hdd_set_pwrparams(pHddCtx);
8278 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008279 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 goto done;
8281 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8285 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 goto done;
8287 default:
8288 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8289 __func__);
8290 return -EOPNOTSUPP;
8291
8292 }
8293
8294 }
8295 else
8296 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308297 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8298 __func__, hdd_device_modetoString(pAdapter->device_mode),
8299 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008300 return -EOPNOTSUPP;
8301 }
8302
8303
8304 if(pRoamProfile)
8305 {
8306 if ( LastBSSType != pRoamProfile->BSSType )
8307 {
8308 /*interface type changed update in wiphy structure*/
8309 wdev->iftype = type;
8310
8311 /*the BSS mode changed, We need to issue disconnect
8312 if connected or in IBSS disconnect state*/
8313 if ( hdd_connGetConnectedBssType(
8314 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8315 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8316 {
8317 /*need to issue a disconnect to CSR.*/
8318 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8319 if( eHAL_STATUS_SUCCESS ==
8320 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8321 pAdapter->sessionId,
8322 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8323 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308324 ret = wait_for_completion_interruptible_timeout(
8325 &pAdapter->disconnect_comp_var,
8326 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8327 if (ret <= 0)
8328 {
8329 hddLog(VOS_TRACE_LEVEL_ERROR,
8330 FL("wait on disconnect_comp_var failed %ld"), ret);
8331 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008332 }
8333 }
8334 }
8335 }
8336
8337done:
8338 /*set bitmask based on updated value*/
8339 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008340
8341 /* Only STA mode support TM now
8342 * all other mode, TM feature should be disabled */
8343 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8344 (~VOS_STA & pHddCtx->concurrency_mode) )
8345 {
8346 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8347 }
8348
Jeff Johnson295189b2012-06-20 16:38:30 -07008349#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308350 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308351 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008352 {
8353 //we are ok to do AMP
8354 pHddCtx->isAmpAllowed = VOS_TRUE;
8355 }
8356#endif //WLAN_BTAMP_FEATURE
8357 EXIT();
8358 return 0;
8359}
8360
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308361/*
8362 * FUNCTION: wlan_hdd_cfg80211_change_iface
8363 * wrapper function to protect the actual implementation from SSR.
8364 */
8365int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8366 struct net_device *ndev,
8367 enum nl80211_iftype type,
8368 u32 *flags,
8369 struct vif_params *params
8370 )
8371{
8372 int ret;
8373
8374 vos_ssr_protect(__func__);
8375 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8376 vos_ssr_unprotect(__func__);
8377
8378 return ret;
8379}
8380
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008381#ifdef FEATURE_WLAN_TDLS
8382static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
8383 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
8384{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008385 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008386 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308387 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308388 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308389 hdd_adapter_t *pAdapter;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008390
8391 ENTER();
8392
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308393 if (!dev) {
8394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8395 return -EINVAL;
8396 }
8397
8398 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8399 if (!pAdapter) {
8400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8401 return -EINVAL;
8402 }
8403
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308404 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008405 {
8406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8407 "Invalid arguments");
8408 return -EINVAL;
8409 }
Hoonki Lee27511902013-03-14 18:19:06 -07008410
8411 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8412 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8413 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008415 "%s: TDLS mode is disabled OR not enabled in FW."
8416 MAC_ADDRESS_STR " Request declined.",
8417 __func__, MAC_ADDR_ARRAY(mac));
8418 return -ENOTSUPP;
8419 }
8420
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008421 if (pHddCtx->isLogpInProgress)
8422 {
8423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8424 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308425 wlan_hdd_tdls_set_link_status(pAdapter,
8426 mac,
8427 eTDLS_LINK_IDLE,
8428 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008429 return -EBUSY;
8430 }
8431
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308432 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008433
8434 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008436 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8437 __func__, MAC_ADDR_ARRAY(mac), update);
8438 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008439 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008440
8441 /* in add station, we accept existing valid staId if there is */
8442 if ((0 == update) &&
8443 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8444 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008445 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008447 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008448 " link_status %d. staId %d. add station ignored.",
8449 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8450 return 0;
8451 }
8452 /* in change station, we accept only when staId is valid */
8453 if ((1 == update) &&
8454 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8455 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8456 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008458 "%s: " MAC_ADDRESS_STR
8459 " link status %d. staId %d. change station %s.",
8460 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8461 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8462 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008463 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008464
8465 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308466 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008467 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8469 "%s: " MAC_ADDRESS_STR
8470 " TDLS setup is ongoing. Request declined.",
8471 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008472 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008473 }
8474
8475 /* first to check if we reached to maximum supported TDLS peer.
8476 TODO: for now, return -EPERM looks working fine,
8477 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308478 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8479 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008480 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8482 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308483 " TDLS Max peer already connected. Request declined."
8484 " Num of peers (%d), Max allowed (%d).",
8485 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8486 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008487 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008488 }
8489 else
8490 {
8491 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308492 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008493 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008494 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8496 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8497 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008498 return -EPERM;
8499 }
8500 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008501 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308502 wlan_hdd_tdls_set_link_status(pAdapter,
8503 mac,
8504 eTDLS_LINK_CONNECTING,
8505 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008506
Jeff Johnsond75fe012013-04-06 10:53:06 -07008507 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308508 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008509 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008511 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008512 if(StaParams->htcap_present)
8513 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008515 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008517 "ht_capa->extended_capabilities: %0x",
8518 StaParams->HTCap.extendedHtCapInfo);
8519 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008521 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008523 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008524 if(StaParams->vhtcap_present)
8525 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008527 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8528 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8529 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8530 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008531 {
8532 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008534 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008536 "[%d]: %x ", i, StaParams->supported_rates[i]);
8537 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008538 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308539 else if ((1 == update) && (NULL == StaParams))
8540 {
8541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8542 "%s : update is true, but staParams is NULL. Error!", __func__);
8543 return -EPERM;
8544 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008545
8546 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8547
8548 if (!update)
8549 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308550 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008551 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308552 if (ret != eHAL_STATUS_SUCCESS) {
8553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to add TDLS peer STA"));
8554 return -EPERM;
8555 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008556 }
8557 else
8558 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308559 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008560 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308561 if (ret != eHAL_STATUS_SUCCESS) {
8562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8563 return -EPERM;
8564 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008565 }
8566
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308567 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008568 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8569
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308570 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008571 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308573 "%s: timeout waiting for tdls add station indication %ld",
8574 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008575 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008576 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308577
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008578 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8579 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008581 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008582 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008583 }
8584
8585 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008586
8587error:
Atul Mittal115287b2014-07-08 13:26:33 +05308588 wlan_hdd_tdls_set_link_status(pAdapter,
8589 mac,
8590 eTDLS_LINK_IDLE,
8591 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008592 return -EPERM;
8593
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008594}
8595#endif
8596
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308597static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 struct net_device *dev,
8599 u8 *mac,
8600 struct station_parameters *params)
8601{
8602 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308603 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308604 hdd_context_t *pHddCtx;
8605 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308607 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008608#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008609 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008610 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308611 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008612#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008613
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308614 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308615
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308616 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308617 if ((NULL == pAdapter))
8618 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308620 "invalid adapter ");
8621 return -EINVAL;
8622 }
8623
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308624 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8625 TRACE_CODE_HDD_CHANGE_STATION,
8626 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308628
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308629 ret = wlan_hdd_validate_context(pHddCtx);
8630 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308631 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308632 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308633 }
8634
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308635 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8636
8637 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008638 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8640 "invalid HDD station context");
8641 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008642 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008643 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8644
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008645 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8646 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008648 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308650 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008651 WLANTL_STA_AUTHENTICATED);
8652
Gopichand Nakkala29149562013-05-10 21:43:41 +05308653 if (status != VOS_STATUS_SUCCESS)
8654 {
8655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8656 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8657 return -EINVAL;
8658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008659 }
8660 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008661 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8662 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308663#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008664 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8665 StaParams.capability = params->capability;
8666 StaParams.uapsd_queues = params->uapsd_queues;
8667 StaParams.max_sp = params->max_sp;
8668
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308669 /* Convert (first channel , number of channels) tuple to
8670 * the total list of channels. This goes with the assumption
8671 * that if the first channel is < 14, then the next channels
8672 * are an incremental of 1 else an incremental of 4 till the number
8673 * of channels.
8674 */
8675 if (0 != params->supported_channels_len) {
8676 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8677 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8678 {
8679 int wifi_chan_index;
8680 StaParams.supported_channels[j] = params->supported_channels[i];
8681 wifi_chan_index =
8682 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8683 no_of_channels = params->supported_channels[i+1];
8684 for(k=1; k <= no_of_channels; k++)
8685 {
8686 StaParams.supported_channels[j+1] =
8687 StaParams.supported_channels[j] + wifi_chan_index;
8688 j+=1;
8689 }
8690 }
8691 StaParams.supported_channels_len = j;
8692 }
8693 vos_mem_copy(StaParams.supported_oper_classes,
8694 params->supported_oper_classes,
8695 params->supported_oper_classes_len);
8696 StaParams.supported_oper_classes_len =
8697 params->supported_oper_classes_len;
8698
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008699 if (0 != params->ext_capab_len)
8700 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8701 sizeof(StaParams.extn_capability));
8702
8703 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008704 {
8705 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008706 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008707 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008708
8709 StaParams.supported_rates_len = params->supported_rates_len;
8710
8711 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8712 * The supported_rates array , for all the structures propogating till Add Sta
8713 * to the firmware has to be modified , if the supplicant (ieee80211) is
8714 * modified to send more rates.
8715 */
8716
8717 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8718 */
8719 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8720 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8721
8722 if (0 != StaParams.supported_rates_len) {
8723 int i = 0;
8724 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8725 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008727 "Supported Rates with Length %d", StaParams.supported_rates_len);
8728 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008730 "[%d]: %0x", i, StaParams.supported_rates[i]);
8731 }
8732
8733 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008734 {
8735 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008736 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008737 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008738
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008739 if (0 != params->ext_capab_len ) {
8740 /*Define A Macro : TODO Sunil*/
8741 if ((1<<4) & StaParams.extn_capability[3]) {
8742 isBufSta = 1;
8743 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308744 /* TDLS Channel Switching Support */
8745 if ((1<<6) & StaParams.extn_capability[3]) {
8746 isOffChannelSupported = 1;
8747 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008748 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308749 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8750 &StaParams, isBufSta,
8751 isOffChannelSupported);
8752
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308753 if (VOS_STATUS_SUCCESS != status) {
8754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8755 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8756 return -EINVAL;
8757 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008758 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8759
8760 if (VOS_STATUS_SUCCESS != status) {
8761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8762 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8763 return -EINVAL;
8764 }
8765 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008766#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308767 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008768 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 return status;
8770}
8771
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308772static int wlan_hdd_change_station(struct wiphy *wiphy,
8773 struct net_device *dev,
8774 u8 *mac,
8775 struct station_parameters *params)
8776{
8777 int ret;
8778
8779 vos_ssr_protect(__func__);
8780 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8781 vos_ssr_unprotect(__func__);
8782
8783 return ret;
8784}
8785
Jeff Johnson295189b2012-06-20 16:38:30 -07008786/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308787 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008788 * This function is used to initialize the key information
8789 */
8790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308791static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 struct net_device *ndev,
8793 u8 key_index, bool pairwise,
8794 const u8 *mac_addr,
8795 struct key_params *params
8796 )
8797#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308798static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 struct net_device *ndev,
8800 u8 key_index, const u8 *mac_addr,
8801 struct key_params *params
8802 )
8803#endif
8804{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008806 tCsrRoamSetKey setKey;
8807 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308808 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008809 v_U32_t roamId= 0xFF;
8810 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 hdd_hostapd_state_t *pHostapdState;
8812 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008813 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308814 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008815
8816 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308817
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308818 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8819 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8820 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308821 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8822 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308823 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008824 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308825 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008826 }
8827
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308828 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8829 __func__, hdd_device_modetoString(pAdapter->device_mode),
8830 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008831
8832 if (CSR_MAX_NUM_KEY <= key_index)
8833 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 key_index);
8836
8837 return -EINVAL;
8838 }
8839
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008840 if (CSR_MAX_KEY_LEN < params->key_len)
8841 {
8842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8843 params->key_len);
8844
8845 return -EINVAL;
8846 }
8847
8848 hddLog(VOS_TRACE_LEVEL_INFO,
8849 "%s: called with key index = %d & key length %d",
8850 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008851
8852 /*extract key idx, key len and key*/
8853 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8854 setKey.keyId = key_index;
8855 setKey.keyLength = params->key_len;
8856 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8857
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008858 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008859 {
8860 case WLAN_CIPHER_SUITE_WEP40:
8861 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8862 break;
8863
8864 case WLAN_CIPHER_SUITE_WEP104:
8865 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8866 break;
8867
8868 case WLAN_CIPHER_SUITE_TKIP:
8869 {
8870 u8 *pKey = &setKey.Key[0];
8871 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8872
8873 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8874
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008875 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008876
8877 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008878 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 |--------------|----------|----------|
8880 <---16bytes---><--8bytes--><--8bytes-->
8881
8882 */
8883 /*Sme expects the 32 bytes key to be in the below order
8884
8885 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008886 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 |--------------|----------|----------|
8888 <---16bytes---><--8bytes--><--8bytes-->
8889 */
8890 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008891 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008892
8893 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008894 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008895
8896 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008897 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008898
8899
8900 break;
8901 }
8902
8903 case WLAN_CIPHER_SUITE_CCMP:
8904 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8905 break;
8906
8907#ifdef FEATURE_WLAN_WAPI
8908 case WLAN_CIPHER_SUITE_SMS4:
8909 {
8910 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8911 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8912 params->key, params->key_len);
8913 return 0;
8914 }
8915#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008916
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008917#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 case WLAN_CIPHER_SUITE_KRK:
8919 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8920 break;
8921#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008922
8923#ifdef WLAN_FEATURE_11W
8924 case WLAN_CIPHER_SUITE_AES_CMAC:
8925 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008926 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008927#endif
8928
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308932 status = -EOPNOTSUPP;
8933 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 }
8935
8936 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8937 __func__, setKey.encType);
8938
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008939 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008940#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8941 (!pairwise)
8942#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008943 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008944#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008945 )
8946 {
8947 /* set group key*/
8948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8949 "%s- %d: setting Broadcast key",
8950 __func__, __LINE__);
8951 setKey.keyDirection = eSIR_RX_ONLY;
8952 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8953 }
8954 else
8955 {
8956 /* set pairwise key*/
8957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8958 "%s- %d: setting pairwise key",
8959 __func__, __LINE__);
8960 setKey.keyDirection = eSIR_TX_RX;
8961 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8962 }
8963 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8964 {
8965 setKey.keyDirection = eSIR_TX_RX;
8966 /*Set the group key*/
8967 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8968 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008969
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008970 if ( 0 != status )
8971 {
8972 hddLog(VOS_TRACE_LEVEL_ERROR,
8973 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308974 status = -EINVAL;
8975 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008976 }
8977 /*Save the keys here and call sme_RoamSetKey for setting
8978 the PTK after peer joins the IBSS network*/
8979 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8980 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308981 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008982 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308983 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8984 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8985 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008987 if( pHostapdState->bssState == BSS_START )
8988 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8990
8991 if ( status != eHAL_STATUS_SUCCESS )
8992 {
8993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8994 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8995 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308996 status = -EINVAL;
8997 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 }
8999 }
9000
9001 /* Saving WEP keys */
9002 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9003 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9004 {
9005 //Save the wep key in ap context. Issue setkey after the BSS is started.
9006 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9007 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9008 }
9009 else
9010 {
9011 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009012 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9014 }
9015 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009016 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9017 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 {
9019 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9020 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9021
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9023 if (!pairwise)
9024#else
9025 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9026#endif
9027 {
9028 /* set group key*/
9029 if (pHddStaCtx->roam_info.deferKeyComplete)
9030 {
9031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9032 "%s- %d: Perform Set key Complete",
9033 __func__, __LINE__);
9034 hdd_PerformRoamSetKeyComplete(pAdapter);
9035 }
9036 }
9037
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9039
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009040 pWextState->roamProfile.Keys.defaultIndex = key_index;
9041
9042
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009043 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009044 params->key, params->key_len);
9045
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309046
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9048
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309049 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309051 __func__, setKey.peerMac[0], setKey.peerMac[1],
9052 setKey.peerMac[2], setKey.peerMac[3],
9053 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 setKey.keyDirection);
9055
Nirav Shah4f765af2015-01-21 19:51:30 +05309056 /* Wait for EAPOL M4 before setting key.
9057 * No need to consider Dynamic WEP as we will receive M8.
9058 */
9059 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
9060 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
9061 ( 1
9062#if defined WLAN_FEATURE_VOWIFI_11R
9063 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
9064 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
9065#endif
9066#ifdef FEATURE_WLAN_ESE
9067 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
9068 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
9069#endif
9070 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07009071 {
Nirav Shah4f765af2015-01-21 19:51:30 +05309072 vos_status = wlan_hdd_check_ula_done(pAdapter);
9073
9074 if ( vos_status != VOS_STATUS_SUCCESS )
9075 {
9076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009077 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9078 __LINE__, vos_status );
9079
Nirav Shah4f765af2015-01-21 19:51:30 +05309080 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009081
Nirav Shah4f765af2015-01-21 19:51:30 +05309082 status = -EINVAL;
9083 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009084
Nirav Shah4f765af2015-01-21 19:51:30 +05309085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 }
9087
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009088#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309089 /* The supplicant may attempt to set the PTK once pre-authentication
9090 is done. Save the key in the UMAC and include it in the ADD BSS
9091 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009092 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309093 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009094 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309095 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9096 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309097 status = 0;
9098 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309099 }
9100 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9101 {
9102 hddLog(VOS_TRACE_LEVEL_ERROR,
9103 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309104 status = -EINVAL;
9105 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009106 }
9107#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009108
9109 /* issue set key request to SME*/
9110 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9111 pAdapter->sessionId, &setKey, &roamId );
9112
9113 if ( 0 != status )
9114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309115 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9117 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309118 status = -EINVAL;
9119 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009120 }
9121
9122
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309123 /* in case of IBSS as there was no information available about WEP keys during
9124 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009125 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309126 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9127 !( ( IW_AUTH_KEY_MGMT_802_1X
9128 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009129 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9130 )
9131 &&
9132 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9133 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9134 )
9135 )
9136 {
9137 setKey.keyDirection = eSIR_RX_ONLY;
9138 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9139
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309140 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309142 __func__, setKey.peerMac[0], setKey.peerMac[1],
9143 setKey.peerMac[2], setKey.peerMac[3],
9144 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 setKey.keyDirection);
9146
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309147 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 pAdapter->sessionId, &setKey, &roamId );
9149
9150 if ( 0 != status )
9151 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309152 hddLog(VOS_TRACE_LEVEL_ERROR,
9153 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 __func__, status);
9155 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309156 status = -EINVAL;
9157 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 }
9159 }
9160 }
9161
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309162end:
9163 /* Need to clear any trace of key value in the memory.
9164 * Thus zero out the memory even though it is local
9165 * variable.
9166 */
9167 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309168 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309169 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009170}
9171
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9173static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9174 struct net_device *ndev,
9175 u8 key_index, bool pairwise,
9176 const u8 *mac_addr,
9177 struct key_params *params
9178 )
9179#else
9180static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9181 struct net_device *ndev,
9182 u8 key_index, const u8 *mac_addr,
9183 struct key_params *params
9184 )
9185#endif
9186{
9187 int ret;
9188 vos_ssr_protect(__func__);
9189#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9190 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9191 mac_addr, params);
9192#else
9193 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9194 params);
9195#endif
9196 vos_ssr_unprotect(__func__);
9197
9198 return ret;
9199}
9200
Jeff Johnson295189b2012-06-20 16:38:30 -07009201/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309202 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 * This function is used to get the key information
9204 */
9205#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309206static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309207 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309209 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009210 const u8 *mac_addr, void *cookie,
9211 void (*callback)(void *cookie, struct key_params*)
9212 )
9213#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309214static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309215 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 struct net_device *ndev,
9217 u8 key_index, const u8 *mac_addr, void *cookie,
9218 void (*callback)(void *cookie, struct key_params*)
9219 )
9220#endif
9221{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309222 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309223 hdd_wext_state_t *pWextState = NULL;
9224 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309226 hdd_context_t *pHddCtx;
9227 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009228
9229 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309230
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309231 if (NULL == pAdapter)
9232 {
9233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9234 "%s: HDD adapter is Null", __func__);
9235 return -ENODEV;
9236 }
9237
9238 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9239 ret = wlan_hdd_validate_context(pHddCtx);
9240 if (0 != ret)
9241 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309242 return ret;
9243 }
9244
9245 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9246 pRoamProfile = &(pWextState->roamProfile);
9247
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309248 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9249 __func__, hdd_device_modetoString(pAdapter->device_mode),
9250 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309251
Jeff Johnson295189b2012-06-20 16:38:30 -07009252 memset(&params, 0, sizeof(params));
9253
9254 if (CSR_MAX_NUM_KEY <= key_index)
9255 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309258 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009259
9260 switch(pRoamProfile->EncryptionType.encryptionType[0])
9261 {
9262 case eCSR_ENCRYPT_TYPE_NONE:
9263 params.cipher = IW_AUTH_CIPHER_NONE;
9264 break;
9265
9266 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9267 case eCSR_ENCRYPT_TYPE_WEP40:
9268 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9269 break;
9270
9271 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9272 case eCSR_ENCRYPT_TYPE_WEP104:
9273 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9274 break;
9275
9276 case eCSR_ENCRYPT_TYPE_TKIP:
9277 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9278 break;
9279
9280 case eCSR_ENCRYPT_TYPE_AES:
9281 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9282 break;
9283
9284 default:
9285 params.cipher = IW_AUTH_CIPHER_NONE;
9286 break;
9287 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309288
c_hpothuaaf19692014-05-17 17:01:48 +05309289 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9290 TRACE_CODE_HDD_CFG80211_GET_KEY,
9291 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309292
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9294 params.seq_len = 0;
9295 params.seq = NULL;
9296 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9297 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309298 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 return 0;
9300}
9301
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9303static int wlan_hdd_cfg80211_get_key(
9304 struct wiphy *wiphy,
9305 struct net_device *ndev,
9306 u8 key_index, bool pairwise,
9307 const u8 *mac_addr, void *cookie,
9308 void (*callback)(void *cookie, struct key_params*)
9309 )
9310#else
9311static int wlan_hdd_cfg80211_get_key(
9312 struct wiphy *wiphy,
9313 struct net_device *ndev,
9314 u8 key_index, const u8 *mac_addr, void *cookie,
9315 void (*callback)(void *cookie, struct key_params*)
9316 )
9317#endif
9318{
9319 int ret;
9320
9321 vos_ssr_protect(__func__);
9322#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9323 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9324 mac_addr, cookie, callback);
9325#else
9326 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9327 callback);
9328#endif
9329 vos_ssr_unprotect(__func__);
9330
9331 return ret;
9332}
9333
Jeff Johnson295189b2012-06-20 16:38:30 -07009334/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309335 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 * This function is used to delete the key information
9337 */
9338#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309339static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309341 u8 key_index,
9342 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 const u8 *mac_addr
9344 )
9345#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309346static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 struct net_device *ndev,
9348 u8 key_index,
9349 const u8 *mac_addr
9350 )
9351#endif
9352{
9353 int status = 0;
9354
9355 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309356 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 //it is observed that this is invalidating peer
9358 //key index whenever re-key is done. This is affecting data link.
9359 //It should be ok to ignore del_key.
9360#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309361 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9362 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009363 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9364 tCsrRoamSetKey setKey;
9365 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309366
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 ENTER();
9368
9369 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9370 __func__,pAdapter->device_mode);
9371
9372 if (CSR_MAX_NUM_KEY <= key_index)
9373 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 key_index);
9376
9377 return -EINVAL;
9378 }
9379
9380 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9381 setKey.keyId = key_index;
9382
9383 if (mac_addr)
9384 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9385 else
9386 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9387
9388 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9389
9390 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309392 )
9393 {
9394
9395 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9397 if( pHostapdState->bssState == BSS_START)
9398 {
9399 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 if ( status != eHAL_STATUS_SUCCESS )
9402 {
9403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9404 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9405 __LINE__, status );
9406 }
9407 }
9408 }
9409 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309410 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 )
9412 {
9413 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9414
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309415 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9416
9417 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419 __func__, setKey.peerMac[0], setKey.peerMac[1],
9420 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309422 if(pAdapter->sessionCtx.station.conn_info.connState ==
9423 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309425 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309427
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 if ( 0 != status )
9429 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309430 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 "%s: sme_RoamSetKey failure, returned %d",
9432 __func__, status);
9433 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9434 return -EINVAL;
9435 }
9436 }
9437 }
9438#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009439 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 return status;
9441}
9442
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309443#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9444static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9445 struct net_device *ndev,
9446 u8 key_index,
9447 bool pairwise,
9448 const u8 *mac_addr
9449 )
9450#else
9451static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9452 struct net_device *ndev,
9453 u8 key_index,
9454 const u8 *mac_addr
9455 )
9456#endif
9457{
9458 int ret;
9459
9460 vos_ssr_protect(__func__);
9461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9462 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9463 mac_addr);
9464#else
9465 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9466#endif
9467 vos_ssr_unprotect(__func__);
9468
9469 return ret;
9470}
9471
Jeff Johnson295189b2012-06-20 16:38:30 -07009472/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309473 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 * This function is used to set the default tx key index
9475 */
9476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309477static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 struct net_device *ndev,
9479 u8 key_index,
9480 bool unicast, bool multicast)
9481#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309482static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 struct net_device *ndev,
9484 u8 key_index)
9485#endif
9486{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309488 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309489 hdd_wext_state_t *pWextState;
9490 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309491 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009492
9493 ENTER();
9494
Gopichand Nakkala29149562013-05-10 21:43:41 +05309495 if ((NULL == pAdapter))
9496 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309498 "invalid adapter");
9499 return -EINVAL;
9500 }
9501
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309502 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9503 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9504 pAdapter->sessionId, key_index));
9505
Gopichand Nakkala29149562013-05-10 21:43:41 +05309506 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9507 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9508
9509 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9510 {
9511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9512 "invalid Wext state or HDD context");
9513 return -EINVAL;
9514 }
9515
Arif Hussain6d2a3322013-11-17 19:50:10 -08009516 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309518
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 if (CSR_MAX_NUM_KEY <= key_index)
9520 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309521 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009522 key_index);
9523
9524 return -EINVAL;
9525 }
9526
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309527 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9528 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309529 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009530 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309531 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009532 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309533
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009535 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309536 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309538 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009539 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309540 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009541 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309543 {
9544 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309546
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 tCsrRoamSetKey setKey;
9548 v_U32_t roamId= 0xFF;
9549 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309550
9551 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309553
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 Keys->defaultIndex = (u8)key_index;
9555 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9556 setKey.keyId = key_index;
9557 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309558
9559 vos_mem_copy(&setKey.Key[0],
9560 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309562
Gopichand Nakkala29149562013-05-10 21:43:41 +05309563 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309564
9565 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009566 &pHddStaCtx->conn_info.bssId[0],
9567 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309568
Gopichand Nakkala29149562013-05-10 21:43:41 +05309569 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9570 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9571 eCSR_ENCRYPT_TYPE_WEP104)
9572 {
9573 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9574 even though ap is configured for WEP-40 encryption. In this canse the key length
9575 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9576 type(104) and switching encryption type to 40*/
9577 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9578 eCSR_ENCRYPT_TYPE_WEP40;
9579 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9580 eCSR_ENCRYPT_TYPE_WEP40;
9581 }
9582
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309585
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 if ( 0 != status )
9591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592 hddLog(VOS_TRACE_LEVEL_ERROR,
9593 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 status);
9595 return -EINVAL;
9596 }
9597 }
9598 }
9599
9600 /* In SoftAp mode setting key direction for default mode */
9601 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9602 {
9603 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9604 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9605 (eCSR_ENCRYPT_TYPE_AES !=
9606 pWextState->roamProfile.EncryptionType.encryptionType[0])
9607 )
9608 {
9609 /* Saving key direction for default key index to TX default */
9610 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9611 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9612 }
9613 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309614 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 return status;
9616}
9617
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9619static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9620 struct net_device *ndev,
9621 u8 key_index,
9622 bool unicast, bool multicast)
9623#else
9624static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9625 struct net_device *ndev,
9626 u8 key_index)
9627#endif
9628{
9629 int ret;
9630 vos_ssr_protect(__func__);
9631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9632 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9633 multicast);
9634#else
9635 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9636#endif
9637 vos_ssr_unprotect(__func__);
9638
9639 return ret;
9640}
9641
Jeff Johnson295189b2012-06-20 16:38:30 -07009642/*
9643 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9644 * This function is used to inform the BSS details to nl80211 interface.
9645 */
9646static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9647 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9648{
9649 struct net_device *dev = pAdapter->dev;
9650 struct wireless_dev *wdev = dev->ieee80211_ptr;
9651 struct wiphy *wiphy = wdev->wiphy;
9652 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9653 int chan_no;
9654 int ie_length;
9655 const char *ie;
9656 unsigned int freq;
9657 struct ieee80211_channel *chan;
9658 int rssi = 0;
9659 struct cfg80211_bss *bss = NULL;
9660
9661 ENTER();
9662
9663 if( NULL == pBssDesc )
9664 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009665 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 return bss;
9667 }
9668
9669 chan_no = pBssDesc->channelId;
9670 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9671 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9672
9673 if( NULL == ie )
9674 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009675 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 return bss;
9677 }
9678
9679#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9680 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9681 {
9682 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9683 }
9684 else
9685 {
9686 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9687 }
9688#else
9689 freq = ieee80211_channel_to_frequency(chan_no);
9690#endif
9691
9692 chan = __ieee80211_get_channel(wiphy, freq);
9693
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309694 if (!chan) {
9695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9696 return NULL;
9697 }
9698
Abhishek Singhaee43942014-06-16 18:55:47 +05309699 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009700
Abhishek Singhaee43942014-06-16 18:55:47 +05309701 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309702 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 pBssDesc->capabilityInfo,
9704 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309705 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009706}
9707
9708
9709
9710/*
9711 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9712 * This function is used to inform the BSS details to nl80211 interface.
9713 */
9714struct cfg80211_bss*
9715wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9716 tSirBssDescription *bss_desc
9717 )
9718{
9719 /*
9720 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9721 already exists in bss data base of cfg80211 for that particular BSS ID.
9722 Using cfg80211_inform_bss_frame to update the bss entry instead of
9723 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9724 now there is no possibility to get the mgmt(probe response) frame from PE,
9725 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9726 cfg80211_inform_bss_frame.
9727 */
9728 struct net_device *dev = pAdapter->dev;
9729 struct wireless_dev *wdev = dev->ieee80211_ptr;
9730 struct wiphy *wiphy = wdev->wiphy;
9731 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009732#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9733 qcom_ie_age *qie_age = NULL;
9734 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9735#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009736 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009737#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 const char *ie =
9739 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9740 unsigned int freq;
9741 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309742 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 struct cfg80211_bss *bss_status = NULL;
9744 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9745 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009746 hdd_context_t *pHddCtx;
9747 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009748#ifdef WLAN_OPEN_SOURCE
9749 struct timespec ts;
9750#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009751
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309752 ENTER();
9753
Wilson Yangf80a0542013-10-07 13:02:37 -07009754 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9755 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009756 if (0 != status)
9757 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009758 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009759 }
9760
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309761 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009762 if (!mgmt)
9763 {
9764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9765 "%s: memory allocation failed ", __func__);
9766 return NULL;
9767 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009768
Jeff Johnson295189b2012-06-20 16:38:30 -07009769 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009770
9771#ifdef WLAN_OPEN_SOURCE
9772 /* Android does not want the timestamp from the frame.
9773 Instead it wants a monotonic increasing value */
9774 get_monotonic_boottime(&ts);
9775 mgmt->u.probe_resp.timestamp =
9776 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9777#else
9778 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9780 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009781
9782#endif
9783
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9785 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009786
9787#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9788 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9789 /* Assuming this is the last IE, copy at the end */
9790 ie_length -=sizeof(qcom_ie_age);
9791 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9792 qie_age->element_id = QCOM_VENDOR_IE_ID;
9793 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9794 qie_age->oui_1 = QCOM_OUI1;
9795 qie_age->oui_2 = QCOM_OUI2;
9796 qie_age->oui_3 = QCOM_OUI3;
9797 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9798 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9799#endif
9800
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309802 if (bss_desc->fProbeRsp)
9803 {
9804 mgmt->frame_control |=
9805 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9806 }
9807 else
9808 {
9809 mgmt->frame_control |=
9810 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009812
9813#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309814 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9816 {
9817 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9818 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309819 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9821
9822 {
9823 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9824 }
9825 else
9826 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309827 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9828 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 kfree(mgmt);
9830 return NULL;
9831 }
9832#else
9833 freq = ieee80211_channel_to_frequency(chan_no);
9834#endif
9835 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009836 /*when the band is changed on the fly using the GUI, three things are done
9837 * 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)
9838 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9839 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9840 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9841 * and discards the channels correponding to previous band and calls back with zero bss results.
9842 * 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
9843 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9844 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9845 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9846 * So drop the bss and continue to next bss.
9847 */
9848 if(chan == NULL)
9849 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009851 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009852 return NULL;
9853 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309855 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 * */
9857 if (( eConnectionState_Associated ==
9858 pAdapter->sessionCtx.station.conn_info.connState ) &&
9859 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9860 pAdapter->sessionCtx.station.conn_info.bssId,
9861 WNI_CFG_BSSID_LEN)))
9862 {
9863 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9864 rssi = (pAdapter->rssi * 100);
9865 }
9866 else
9867 {
9868 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9869 }
9870
Nirav Shah20ac06f2013-12-12 18:14:06 +05309871 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9872 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9873 chan->center_freq, (int)(rssi/100));
9874
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9876 frame_len, rssi, GFP_KERNEL);
9877 kfree(mgmt);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309878 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 return bss_status;
9880}
9881
9882/*
9883 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9884 * This function is used to update the BSS data base of CFG8011
9885 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309886struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009887 tCsrRoamInfo *pRoamInfo
9888 )
9889{
9890 tCsrRoamConnectedProfile roamProfile;
9891 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9892 struct cfg80211_bss *bss = NULL;
9893
9894 ENTER();
9895
9896 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9897 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9898
9899 if (NULL != roamProfile.pBssDesc)
9900 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309901 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9902 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009903
9904 if (NULL == bss)
9905 {
9906 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9907 __func__);
9908 }
9909
9910 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9911 }
9912 else
9913 {
9914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9915 __func__);
9916 }
9917 return bss;
9918}
9919
9920/*
9921 * FUNCTION: wlan_hdd_cfg80211_update_bss
9922 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309923static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9924 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309927 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 tCsrScanResultInfo *pScanResult;
9929 eHalStatus status = 0;
9930 tScanResultHandle pResult;
9931 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009932 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009933
9934 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309935
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309936 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9937 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9938 NO_SESSION, pAdapter->sessionId));
9939
Wilson Yangf80a0542013-10-07 13:02:37 -07009940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9941
9942 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9945 "%s:LOGP in Progress. Ignore!!!",__func__);
9946 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 }
9948
Wilson Yangf80a0542013-10-07 13:02:37 -07009949
9950 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309951 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009952 {
9953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9954 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9955 return VOS_STATUS_E_PERM;
9956 }
9957
9958
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 /*
9960 * start getting scan results and populate cgf80211 BSS database
9961 */
9962 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9963
9964 /* no scan results */
9965 if (NULL == pResult)
9966 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309967 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9968 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 return status;
9970 }
9971
9972 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9973
9974 while (pScanResult)
9975 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309976 /*
9977 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9978 * entry already exists in bss data base of cfg80211 for that
9979 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9980 * bss entry instead of cfg80211_inform_bss, But this call expects
9981 * mgmt packet as input. As of now there is no possibility to get
9982 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009983 * ieee80211_mgmt(probe response) and passing to c
9984 * fg80211_inform_bss_frame.
9985 * */
9986
9987 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9988 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309989
Jeff Johnson295189b2012-06-20 16:38:30 -07009990
9991 if (NULL == bss_status)
9992 {
9993 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009994 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 }
9996 else
9997 {
Yue Maf49ba872013-08-19 12:04:25 -07009998 cfg80211_put_bss(
9999#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10000 wiphy,
10001#endif
10002 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 }
10004
10005 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10006 }
10007
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010008 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -070010009
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010010 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010011}
10012
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010013void
10014hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10015{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010017 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010018} /****** end hddPrintMacAddr() ******/
10019
10020void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010021hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010022{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010023 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010024 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010025 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10026 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10027 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010028} /****** end hddPrintPmkId() ******/
10029
10030//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10031//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10032
10033//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10034//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10035
10036#define dump_bssid(bssid) \
10037 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010038 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10039 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010040 }
10041
10042#define dump_pmkid(pMac, pmkid) \
10043 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010044 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10045 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010046 }
10047
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010048#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010049/*
10050 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10051 * This function is used to notify the supplicant of a new PMKSA candidate.
10052 */
10053int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010054 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010055 int index, bool preauth )
10056{
Jeff Johnsone7245742012-09-05 17:12:55 -070010057#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010058 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010059 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010060
10061 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010062 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010063
10064 if( NULL == pRoamInfo )
10065 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010066 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010067 return -EINVAL;
10068 }
10069
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010070 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10071 {
10072 dump_bssid(pRoamInfo->bssid);
10073 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010074 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010075 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010076#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010077 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010078}
10079#endif //FEATURE_WLAN_LFR
10080
Yue Maef608272013-04-08 23:09:17 -070010081#ifdef FEATURE_WLAN_LFR_METRICS
10082/*
10083 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10084 * 802.11r/LFR metrics reporting function to report preauth initiation
10085 *
10086 */
10087#define MAX_LFR_METRICS_EVENT_LENGTH 100
10088VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10089 tCsrRoamInfo *pRoamInfo)
10090{
10091 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10092 union iwreq_data wrqu;
10093
10094 ENTER();
10095
10096 if (NULL == pAdapter)
10097 {
10098 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10099 return VOS_STATUS_E_FAILURE;
10100 }
10101
10102 /* create the event */
10103 memset(&wrqu, 0, sizeof(wrqu));
10104 memset(metrics_notification, 0, sizeof(metrics_notification));
10105
10106 wrqu.data.pointer = metrics_notification;
10107 wrqu.data.length = scnprintf(metrics_notification,
10108 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10109 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10110
10111 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10112
10113 EXIT();
10114
10115 return VOS_STATUS_SUCCESS;
10116}
10117
10118/*
10119 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10120 * 802.11r/LFR metrics reporting function to report preauth completion
10121 * or failure
10122 */
10123VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10124 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10125{
10126 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10127 union iwreq_data wrqu;
10128
10129 ENTER();
10130
10131 if (NULL == pAdapter)
10132 {
10133 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10134 return VOS_STATUS_E_FAILURE;
10135 }
10136
10137 /* create the event */
10138 memset(&wrqu, 0, sizeof(wrqu));
10139 memset(metrics_notification, 0, sizeof(metrics_notification));
10140
10141 scnprintf(metrics_notification, sizeof(metrics_notification),
10142 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10143 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10144
10145 if (1 == preauth_status)
10146 strncat(metrics_notification, " TRUE", 5);
10147 else
10148 strncat(metrics_notification, " FALSE", 6);
10149
10150 wrqu.data.pointer = metrics_notification;
10151 wrqu.data.length = strlen(metrics_notification);
10152
10153 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10154
10155 EXIT();
10156
10157 return VOS_STATUS_SUCCESS;
10158}
10159
10160/*
10161 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10162 * 802.11r/LFR metrics reporting function to report handover initiation
10163 *
10164 */
10165VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10166 tCsrRoamInfo *pRoamInfo)
10167{
10168 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10169 union iwreq_data wrqu;
10170
10171 ENTER();
10172
10173 if (NULL == pAdapter)
10174 {
10175 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10176 return VOS_STATUS_E_FAILURE;
10177 }
10178
10179 /* create the event */
10180 memset(&wrqu, 0, sizeof(wrqu));
10181 memset(metrics_notification, 0, sizeof(metrics_notification));
10182
10183 wrqu.data.pointer = metrics_notification;
10184 wrqu.data.length = scnprintf(metrics_notification,
10185 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10186 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10187
10188 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10189
10190 EXIT();
10191
10192 return VOS_STATUS_SUCCESS;
10193}
10194#endif
10195
Jeff Johnson295189b2012-06-20 16:38:30 -070010196/*
10197 * FUNCTION: hdd_cfg80211_scan_done_callback
10198 * scanning callback function, called after finishing scan
10199 *
10200 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010201static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10203{
10204 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010205 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010207 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010208 struct cfg80211_scan_request *req = NULL;
10209 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010210 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010211 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010212 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010213 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010214
10215 ENTER();
10216
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010217 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10218 if (0 != wlan_hdd_validate_context(pHddCtx)) {
10219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
10220 goto allow_suspend;
10221 }
10222
10223 pScanInfo = &pHddCtx->scan_info;
10224
Jeff Johnson295189b2012-06-20 16:38:30 -070010225 hddLog(VOS_TRACE_LEVEL_INFO,
10226 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010227 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010228 __func__, halHandle, pContext, (int) scanId, (int) status);
10229
Kiet Lamac06e2c2013-10-23 16:25:07 +053010230 pScanInfo->mScanPendingCounter = 0;
10231
Jeff Johnson295189b2012-06-20 16:38:30 -070010232 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010233 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010234 &pScanInfo->scan_req_completion_event,
10235 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010236 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010238 hddLog(VOS_TRACE_LEVEL_ERROR,
10239 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010240 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010241 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 }
10243
Yue Maef608272013-04-08 23:09:17 -070010244 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010245 {
10246 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010247 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010248 }
10249
10250 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010251 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 {
10253 hddLog(VOS_TRACE_LEVEL_INFO,
10254 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010255 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 (int) scanId);
10257 }
10258
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010259 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 pAdapter);
10261
10262 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010263 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010264
10265
10266 /* If any client wait scan result through WEXT
10267 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010268 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 {
10270 /* The other scan request waiting for current scan finish
10271 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010272 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010273 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010274 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 }
10276 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010277 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010278 {
10279 struct net_device *dev = pAdapter->dev;
10280 union iwreq_data wrqu;
10281 int we_event;
10282 char *msg;
10283
10284 memset(&wrqu, '\0', sizeof(wrqu));
10285 we_event = SIOCGIWSCAN;
10286 msg = NULL;
10287 wireless_send_event(dev, we_event, &wrqu, msg);
10288 }
10289 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010290 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010291
10292 /* Get the Scan Req */
10293 req = pAdapter->request;
10294
10295 if (!req)
10296 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010297 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010298 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010299 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 }
10301
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010303 /* Scan is no longer pending */
10304 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010305
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010306 /* last_scan_timestamp is used to decide if new scan
10307 * is needed or not on station interface. If last station
10308 * scan time and new station scan time is less then
10309 * last_scan_timestamp ; driver will return cached scan.
10310 */
10311 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10312 {
10313 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10314
10315 if ( req->n_channels )
10316 {
10317 for (i = 0; i < req->n_channels ; i++ )
10318 {
10319 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10320 }
10321 /* store no of channel scanned */
10322 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10323 }
10324
10325 }
10326
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010327 /*
10328 * cfg80211_scan_done informing NL80211 about completion
10329 * of scanning
10330 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010331 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10332 {
10333 aborted = true;
10334 }
10335 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010336 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010337
Siddharth Bhal76972212014-10-15 16:22:51 +053010338 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10339 /* Generate new random mac addr for next scan */
10340 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10341 hdd_processSpoofMacAddrRequest(pHddCtx);
10342 }
10343
Jeff Johnsone7245742012-09-05 17:12:55 -070010344allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010345 /* release the wake lock at the end of the scan*/
10346 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010347
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010348 /* Acquire wakelock to handle the case where APP's tries to suspend
10349 * immediatly after the driver gets connect request(i.e after scan)
10350 * from supplicant, this result in app's is suspending and not able
10351 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010352 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010353
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010354#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010355 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010356#endif
10357
Jeff Johnson295189b2012-06-20 16:38:30 -070010358 EXIT();
10359 return 0;
10360}
10361
10362/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010363 * FUNCTION: hdd_isConnectionInProgress
10364 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010365 *
10366 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010367v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010368{
10369 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10370 hdd_station_ctx_t *pHddStaCtx = NULL;
10371 hdd_adapter_t *pAdapter = NULL;
10372 VOS_STATUS status = 0;
10373 v_U8_t staId = 0;
10374 v_U8_t *staMac = NULL;
10375
c_hpothu9b781ba2013-12-30 20:57:45 +053010376 if (TRUE == pHddCtx->btCoexModeSet)
10377 {
10378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010379 FL("BTCoex Mode operation in progress"));
10380 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010381 }
10382
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010383 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10384
10385 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10386 {
10387 pAdapter = pAdapterNode->pAdapter;
10388
10389 if( pAdapter )
10390 {
10391 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010392 "%s: Adapter with device mode %s (%d) exists",
10393 __func__, hdd_device_modetoString(pAdapter->device_mode),
10394 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010395 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010396 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10397 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10398 (eConnectionState_Connecting ==
10399 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10400 {
10401 hddLog(VOS_TRACE_LEVEL_ERROR,
10402 "%s: %p(%d) Connection is in progress", __func__,
10403 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10404 return VOS_TRUE;
10405 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010406 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010407 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010408 {
10409 hddLog(VOS_TRACE_LEVEL_ERROR,
10410 "%s: %p(%d) Reassociation is in progress", __func__,
10411 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10412 return VOS_TRUE;
10413 }
10414 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010415 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10416 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010417 {
10418 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10419 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010420 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010421 {
10422 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10423 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010424 "%s: client " MAC_ADDRESS_STR
10425 " is in the middle of WPS/EAPOL exchange.", __func__,
10426 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010427 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010428 }
10429 }
10430 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10431 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10432 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010433 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10434 ptSapContext pSapCtx = NULL;
10435 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10436 if(pSapCtx == NULL){
10437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10438 FL("psapCtx is NULL"));
10439 return VOS_FALSE;
10440 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010441 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10442 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010443 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10444 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010445 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010446 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010447
10448 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010449 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10450 "middle of WPS/EAPOL exchange.", __func__,
10451 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010452 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010453 }
10454 }
10455 }
10456 }
10457 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10458 pAdapterNode = pNext;
10459 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010460 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010461}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010462
10463/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010464 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010465 * this scan respond to scan trigger and update cfg80211 scan database
10466 * later, scan dump command can be used to recieve scan results
10467 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010468int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010469#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10470 struct net_device *dev,
10471#endif
10472 struct cfg80211_scan_request *request)
10473{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010474 hdd_adapter_t *pAdapter = NULL;
10475 hdd_context_t *pHddCtx = NULL;
10476 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010477 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 tCsrScanRequest scanRequest;
10479 tANI_U8 *channelList = NULL, i;
10480 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010481 int status;
10482 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010484 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010485
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10487 struct net_device *dev = NULL;
10488 if (NULL == request)
10489 {
10490 hddLog(VOS_TRACE_LEVEL_ERROR,
10491 "%s: scan req param null", __func__);
10492 return -EINVAL;
10493 }
10494 dev = request->wdev->netdev;
10495#endif
10496
10497 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10498 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10499 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10500
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 ENTER();
10502
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10504 __func__, hdd_device_modetoString(pAdapter->device_mode),
10505 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010506
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010507 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010508 if (0 != status)
10509 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010510 return status;
10511 }
10512
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010513 if (NULL == pwextBuf)
10514 {
10515 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10516 __func__);
10517 return -EIO;
10518 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010519 cfg_param = pHddCtx->cfg_ini;
10520 pScanInfo = &pHddCtx->scan_info;
10521
Jeff Johnson295189b2012-06-20 16:38:30 -070010522#ifdef WLAN_BTAMP_FEATURE
10523 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010524 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010526 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 "%s: No scanning when AMP is on", __func__);
10528 return -EOPNOTSUPP;
10529 }
10530#endif
10531 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010532 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010534 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010535 "%s: Not scanning on device_mode = %s (%d)",
10536 __func__, hdd_device_modetoString(pAdapter->device_mode),
10537 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010538 return -EOPNOTSUPP;
10539 }
10540
10541 if (TRUE == pScanInfo->mScanPending)
10542 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010543 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10544 {
10545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10546 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010547 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 }
10549
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010550 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010551 //Channel and action frame is pending
10552 //Otherwise Cancel Remain On Channel and allow Scan
10553 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010554 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010555 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010557 return -EBUSY;
10558 }
10559
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10561 {
10562 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010563 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010565 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10567 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010568 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 "%s: MAX TM Level Scan not allowed", __func__);
10570 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010571 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 }
10573 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10574
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010575 /* Check if scan is allowed at this point of time.
10576 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010577 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010578 {
10579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10580 return -EBUSY;
10581 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010582
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10584
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010585 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10586 (int)request->n_ssids);
10587
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010588
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010589 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10590 * Becasue of this, driver is assuming that this is not wildcard scan and so
10591 * is not aging out the scan results.
10592 */
10593 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010595 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010596 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010597
10598 if ((request->ssids) && (0 < request->n_ssids))
10599 {
10600 tCsrSSIDInfo *SsidInfo;
10601 int j;
10602 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10603 /* Allocate num_ssid tCsrSSIDInfo structure */
10604 SsidInfo = scanRequest.SSIDs.SSIDList =
10605 ( tCsrSSIDInfo *)vos_mem_malloc(
10606 request->n_ssids*sizeof(tCsrSSIDInfo));
10607
10608 if(NULL == scanRequest.SSIDs.SSIDList)
10609 {
10610 hddLog(VOS_TRACE_LEVEL_ERROR,
10611 "%s: memory alloc failed SSIDInfo buffer", __func__);
10612 return -ENOMEM;
10613 }
10614
10615 /* copy all the ssid's and their length */
10616 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10617 {
10618 /* get the ssid length */
10619 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10620 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10621 SsidInfo->SSID.length);
10622 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10623 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10624 j, SsidInfo->SSID.ssId);
10625 }
10626 /* set the scan type to active */
10627 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10628 }
10629 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010631 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10632 TRACE_CODE_HDD_CFG80211_SCAN,
10633 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 /* set the scan type to active */
10635 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010636 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010637 else
10638 {
10639 /*Set the scan type to default type, in this case it is ACTIVE*/
10640 scanRequest.scanType = pScanInfo->scan_mode;
10641 }
10642 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10643 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010644
10645 /* set BSSType to default type */
10646 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10647
10648 /*TODO: scan the requested channels only*/
10649
10650 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010651 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010653 hddLog(VOS_TRACE_LEVEL_WARN,
10654 "No of Scan Channels exceeded limit: %d", request->n_channels);
10655 request->n_channels = MAX_CHANNEL;
10656 }
10657
10658 hddLog(VOS_TRACE_LEVEL_INFO,
10659 "No of Scan Channels: %d", request->n_channels);
10660
10661
10662 if( request->n_channels )
10663 {
10664 char chList [(request->n_channels*5)+1];
10665 int len;
10666 channelList = vos_mem_malloc( request->n_channels );
10667 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010668 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010669 hddLog(VOS_TRACE_LEVEL_ERROR,
10670 "%s: memory alloc failed channelList", __func__);
10671 status = -ENOMEM;
10672 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010673 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010674
10675 for( i = 0, len = 0; i < request->n_channels ; i++ )
10676 {
10677 channelList[i] = request->channels[i]->hw_value;
10678 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10679 }
10680
Nirav Shah20ac06f2013-12-12 18:14:06 +053010681 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010682 "Channel-List: %s ", chList);
10683 }
c_hpothu53512302014-04-15 18:49:53 +053010684
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010685 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10686 scanRequest.ChannelInfo.ChannelList = channelList;
10687
10688 /* set requestType to full scan */
10689 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10690
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010691 /* if there is back to back scan happening in driver with in
10692 * nDeferScanTimeInterval interval driver should defer new scan request
10693 * and should provide last cached scan results instead of new channel list.
10694 * This rule is not applicable if scan is p2p scan.
10695 * This condition will work only in case when last request no of channels
10696 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010697 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010698 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010699
Agarwal Ashish57e84372014-12-05 18:26:53 +053010700 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10701 {
10702 if ( pScanInfo->last_scan_timestamp !=0 &&
10703 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10704 {
10705 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10706 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10707 vos_mem_compare(pScanInfo->last_scan_channelList,
10708 channelList, pScanInfo->last_scan_numChannels))
10709 {
10710 hddLog(VOS_TRACE_LEVEL_WARN,
10711 " New and old station scan time differ is less then %u",
10712 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10713
10714 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010715 pAdapter);
10716
Agarwal Ashish57e84372014-12-05 18:26:53 +053010717 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010718 "Return old cached scan as all channels and no of channels are same");
10719
Agarwal Ashish57e84372014-12-05 18:26:53 +053010720 if (0 > ret)
10721 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010722
Agarwal Ashish57e84372014-12-05 18:26:53 +053010723 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010724
10725 status = eHAL_STATUS_SUCCESS;
10726 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010727 }
10728 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010729 }
10730
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010731 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10732 * search (Flush on both full scan and social scan but not on single
10733 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10734 */
10735
10736 /* Supplicant does single channel scan after 8-way handshake
10737 * and in that case driver shoudnt flush scan results. If
10738 * driver flushes the scan results here and unfortunately if
10739 * the AP doesnt respond to our probe req then association
10740 * fails which is not desired
10741 */
10742
10743 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10744 {
10745 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10746 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10747 pAdapter->sessionId );
10748 }
10749
10750 if( request->ie_len )
10751 {
10752 /* save this for future association (join requires this) */
10753 /*TODO: Array needs to be converted to dynamic allocation,
10754 * as multiple ie.s can be sent in cfg80211_scan_request structure
10755 * CR 597966
10756 */
10757 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10758 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10759 pScanInfo->scanAddIE.length = request->ie_len;
10760
10761 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10762 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10763 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010765 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010767 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10768 memcpy( pwextBuf->roamProfile.addIEScan,
10769 request->ie, request->ie_len);
10770 }
10771 else
10772 {
10773 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10774 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 }
10776
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010777 }
10778 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10779 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10780
10781 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10782 request->ie_len);
10783 if (pP2pIe != NULL)
10784 {
10785#ifdef WLAN_FEATURE_P2P_DEBUG
10786 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10787 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10788 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010789 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010790 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10791 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10792 "Go nego completed to Connection is started");
10793 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10794 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010795 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010796 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10797 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010798 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010799 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10800 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10801 "Disconnected state to Connection is started");
10802 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10803 "for 4way Handshake");
10804 }
10805#endif
10806
10807 /* no_cck will be set during p2p find to disable 11b rates */
10808 if(TRUE == request->no_cck)
10809 {
10810 hddLog(VOS_TRACE_LEVEL_INFO,
10811 "%s: This is a P2P Search", __func__);
10812 scanRequest.p2pSearch = 1;
10813
10814 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010815 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010816 /* set requestType to P2P Discovery */
10817 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10818 }
10819
10820 /*
10821 Skip Dfs Channel in case of P2P Search
10822 if it is set in ini file
10823 */
10824 if(cfg_param->skipDfsChnlInP2pSearch)
10825 {
10826 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010827 }
10828 else
10829 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010830 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010831 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010832
Agarwal Ashish4f616132013-12-30 23:32:50 +053010833 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 }
10835 }
10836
10837 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10838
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010839#ifdef FEATURE_WLAN_TDLS
10840 /* if tdls disagree scan right now, return immediately.
10841 tdls will schedule the scan when scan is allowed. (return SUCCESS)
10842 or will reject the scan if any TDLS is in progress. (return -EBUSY)
10843 */
10844 status = wlan_hdd_tdls_scan_callback (pAdapter,
10845 wiphy,
10846#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10847 dev,
10848#endif
10849 request);
10850 if(status <= 0)
10851 {
10852 if(!status)
10853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10854 "scan rejected %d", __func__, status);
10855 else
10856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10857 __func__, status);
10858
10859 return status;
10860 }
10861#endif
10862
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010863 /* acquire the wakelock to avoid the apps suspend during the scan. To
10864 * address the following issues.
10865 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10866 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10867 * for long time, this result in apps running at full power for long time.
10868 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10869 * be stuck in full power because of resume BMPS
10870 */
10871 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010872
Nirav Shah20ac06f2013-12-12 18:14:06 +053010873 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10874 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010875 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10876 scanRequest.requestType, scanRequest.scanType,
10877 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010878 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10879
Siddharth Bhal76972212014-10-15 16:22:51 +053010880 if (pHddCtx->spoofMacAddr.isEnabled)
10881 {
10882 hddLog(VOS_TRACE_LEVEL_INFO,
10883 "%s: MAC Spoofing enabled for current scan", __func__);
10884 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10885 * to fill TxBds for probe request during current scan
10886 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053010887 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053010888 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053010889
10890 if(status != VOS_STATUS_SUCCESS)
10891 {
10892 hdd_allow_suspend();
10893 status = -EFAULT;
10894 goto free_mem;
10895 }
Siddharth Bhal76972212014-10-15 16:22:51 +053010896 }
10897
Jeff Johnsone7245742012-09-05 17:12:55 -070010898 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010899 pAdapter->sessionId, &scanRequest, &scanId,
10900 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010901
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 if (eHAL_STATUS_SUCCESS != status)
10903 {
10904 hddLog(VOS_TRACE_LEVEL_ERROR,
10905 "%s: sme_ScanRequest returned error %d", __func__, status);
10906 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010907 if(eHAL_STATUS_RESOURCES == status)
10908 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010909 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10910 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010911 status = -EBUSY;
10912 } else {
10913 status = -EIO;
10914 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010915 hdd_allow_suspend();
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010916
10917#ifdef FEATURE_WLAN_TDLS
10918 wlan_hdd_tdls_scan_done_callback(pAdapter);
10919#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010920 goto free_mem;
10921 }
10922
10923 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010924 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010925 pAdapter->request = request;
10926 pScanInfo->scanId = scanId;
10927
10928 complete(&pScanInfo->scan_req_completion_event);
10929
10930free_mem:
10931 if( scanRequest.SSIDs.SSIDList )
10932 {
10933 vos_mem_free(scanRequest.SSIDs.SSIDList);
10934 }
10935
10936 if( channelList )
10937 vos_mem_free( channelList );
10938
10939 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 return status;
10941}
10942
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010943int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10944#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10945 struct net_device *dev,
10946#endif
10947 struct cfg80211_scan_request *request)
10948{
10949 int ret;
10950
10951 vos_ssr_protect(__func__);
10952 ret = __wlan_hdd_cfg80211_scan(wiphy,
10953#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10954 dev,
10955#endif
10956 request);
10957 vos_ssr_unprotect(__func__);
10958
10959 return ret;
10960}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010961
10962void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10963{
10964 v_U8_t iniDot11Mode =
10965 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10966 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10967
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010968 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10969 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010970 switch ( iniDot11Mode )
10971 {
10972 case eHDD_DOT11_MODE_AUTO:
10973 case eHDD_DOT11_MODE_11ac:
10974 case eHDD_DOT11_MODE_11ac_ONLY:
10975#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010976 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10977 sme_IsFeatureSupportedByFW(DOT11AC) )
10978 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10979 else
10980 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010981#else
10982 hddDot11Mode = eHDD_DOT11_MODE_11n;
10983#endif
10984 break;
10985 case eHDD_DOT11_MODE_11n:
10986 case eHDD_DOT11_MODE_11n_ONLY:
10987 hddDot11Mode = eHDD_DOT11_MODE_11n;
10988 break;
10989 default:
10990 hddDot11Mode = iniDot11Mode;
10991 break;
10992 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010993#ifdef WLAN_FEATURE_AP_HT40_24G
10994 if (operationChannel > SIR_11B_CHANNEL_END)
10995#endif
10996 {
10997 /* This call decides required channel bonding mode */
10998 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010999 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11000 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011001 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011002}
11003
Jeff Johnson295189b2012-06-20 16:38:30 -070011004/*
11005 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011006 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011007 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011008int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011009 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011010{
11011 int status = 0;
11012 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011013 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011014 v_U32_t roamId;
11015 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 eCsrAuthType RSNAuthType;
11017
11018 ENTER();
11019
11020 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011021 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11022
11023 status = wlan_hdd_validate_context(pHddCtx);
11024 if (status)
11025 {
Yue Mae36e3552014-03-05 17:06:20 -080011026 return status;
11027 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011028
Jeff Johnson295189b2012-06-20 16:38:30 -070011029 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11030 {
11031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11032 return -EINVAL;
11033 }
11034
11035 pRoamProfile = &pWextState->roamProfile;
11036
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011037 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011038 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011039 hdd_station_ctx_t *pHddStaCtx;
11040 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011041
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011042 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011043 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11044 {
11045 /*QoS not enabled in cfg file*/
11046 pRoamProfile->uapsd_mask = 0;
11047 }
11048 else
11049 {
11050 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011051 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011052 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11053 }
11054
11055 pRoamProfile->SSIDs.numOfSSIDs = 1;
11056 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11057 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011058 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011059 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11060 ssid, ssid_len);
11061
11062 if (bssid)
11063 {
11064 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11065 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11066 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011067 /* Save BSSID in seperate variable as well, as RoamProfile
11068 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 case of join failure we should send valid BSSID to supplicant
11070 */
11071 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11072 WNI_CFG_BSSID_LEN);
11073 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011074 else
11075 {
11076 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11077 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011078
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011079 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11080 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011081 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11082 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011083 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011084 /*set gen ie*/
11085 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11086 /*set auth*/
11087 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11088 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011089#ifdef FEATURE_WLAN_WAPI
11090 if (pAdapter->wapi_info.nWapiMode)
11091 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011092 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 switch (pAdapter->wapi_info.wapiAuthMode)
11094 {
11095 case WAPI_AUTH_MODE_PSK:
11096 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011097 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 pAdapter->wapi_info.wapiAuthMode);
11099 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11100 break;
11101 }
11102 case WAPI_AUTH_MODE_CERT:
11103 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011104 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 pAdapter->wapi_info.wapiAuthMode);
11106 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11107 break;
11108 }
11109 } // End of switch
11110 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11111 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11112 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011113 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 pRoamProfile->AuthType.numEntries = 1;
11115 pRoamProfile->EncryptionType.numEntries = 1;
11116 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11117 pRoamProfile->mcEncryptionType.numEntries = 1;
11118 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11119 }
11120 }
11121#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011122#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011123 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011124 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11125 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11126 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011127 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11128 sizeof (tSirGtkOffloadParams));
11129 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011130 }
11131#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 pRoamProfile->csrPersona = pAdapter->device_mode;
11133
Jeff Johnson32d95a32012-09-10 13:15:23 -070011134 if( operatingChannel )
11135 {
11136 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11137 pRoamProfile->ChannelInfo.numOfChannels = 1;
11138 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011139 else
11140 {
11141 pRoamProfile->ChannelInfo.ChannelList = NULL;
11142 pRoamProfile->ChannelInfo.numOfChannels = 0;
11143 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011144 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11145 {
11146 hdd_select_cbmode(pAdapter,operatingChannel);
11147 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011148
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011149 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11150 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011151 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011152 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011153 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11154 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011155 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11156 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011157 {
11158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11159 "%s: Set HDD connState to eConnectionState_Connecting",
11160 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011161 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11162 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011163 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011164 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 pAdapter->sessionId, pRoamProfile, &roamId);
11166
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011167 if ((eHAL_STATUS_SUCCESS != status) &&
11168 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11169 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011170
11171 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11173 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11174 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011175 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011176 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011177 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011178
11179 pRoamProfile->ChannelInfo.ChannelList = NULL;
11180 pRoamProfile->ChannelInfo.numOfChannels = 0;
11181
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 }
11183 else
11184 {
11185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11186 return -EINVAL;
11187 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011188 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 return status;
11190}
11191
11192/*
11193 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11194 * This function is used to set the authentication type (OPEN/SHARED).
11195 *
11196 */
11197static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11198 enum nl80211_auth_type auth_type)
11199{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011200 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011201 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11202
11203 ENTER();
11204
11205 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011206 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011209 hddLog(VOS_TRACE_LEVEL_INFO,
11210 "%s: set authentication type to AUTOSWITCH", __func__);
11211 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11212 break;
11213
11214 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011215#ifdef WLAN_FEATURE_VOWIFI_11R
11216 case NL80211_AUTHTYPE_FT:
11217#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011218 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 "%s: set authentication type to OPEN", __func__);
11220 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11221 break;
11222
11223 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 "%s: set authentication type to SHARED", __func__);
11226 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11227 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011228#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011230 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 "%s: set authentication type to CCKM WPA", __func__);
11232 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11233 break;
11234#endif
11235
11236
11237 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011238 hddLog(VOS_TRACE_LEVEL_ERROR,
11239 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011240 auth_type);
11241 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11242 return -EINVAL;
11243 }
11244
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011245 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 pHddStaCtx->conn_info.authType;
11247 return 0;
11248}
11249
11250/*
11251 * FUNCTION: wlan_hdd_set_akm_suite
11252 * This function is used to set the key mgmt type(PSK/8021x).
11253 *
11254 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011255static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 u32 key_mgmt
11257 )
11258{
11259 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11260 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011261 /* Should be in ieee802_11_defs.h */
11262#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11263#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 /*set key mgmt type*/
11265 switch(key_mgmt)
11266 {
11267 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011268 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011269#ifdef WLAN_FEATURE_VOWIFI_11R
11270 case WLAN_AKM_SUITE_FT_PSK:
11271#endif
11272 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011273 __func__);
11274 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11275 break;
11276
11277 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011278 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011279#ifdef WLAN_FEATURE_VOWIFI_11R
11280 case WLAN_AKM_SUITE_FT_8021X:
11281#endif
11282 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 __func__);
11284 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11285 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011286#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011287#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11288#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11289 case WLAN_AKM_SUITE_CCKM:
11290 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11291 __func__);
11292 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11293 break;
11294#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011295#ifndef WLAN_AKM_SUITE_OSEN
11296#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11297 case WLAN_AKM_SUITE_OSEN:
11298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11299 __func__);
11300 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11301 break;
11302#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011303
11304 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 __func__, key_mgmt);
11307 return -EINVAL;
11308
11309 }
11310 return 0;
11311}
11312
11313/*
11314 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011315 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 * (NONE/WEP40/WEP104/TKIP/CCMP).
11317 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011318static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11319 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 bool ucast
11321 )
11322{
11323 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011324 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11326
11327 ENTER();
11328
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011332 __func__, cipher);
11333 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11334 }
11335 else
11336 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011337
Jeff Johnson295189b2012-06-20 16:38:30 -070011338 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011339 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 {
11341 case IW_AUTH_CIPHER_NONE:
11342 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11343 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011344
Jeff Johnson295189b2012-06-20 16:38:30 -070011345 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011346 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011348
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011350 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011352
Jeff Johnson295189b2012-06-20 16:38:30 -070011353 case WLAN_CIPHER_SUITE_TKIP:
11354 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11355 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011356
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 case WLAN_CIPHER_SUITE_CCMP:
11358 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11359 break;
11360#ifdef FEATURE_WLAN_WAPI
11361 case WLAN_CIPHER_SUITE_SMS4:
11362 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11363 break;
11364#endif
11365
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011366#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 case WLAN_CIPHER_SUITE_KRK:
11368 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11369 break;
11370#endif
11371 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 __func__, cipher);
11374 return -EOPNOTSUPP;
11375 }
11376 }
11377
11378 if (ucast)
11379 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011380 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 __func__, encryptionType);
11382 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11383 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011384 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011385 encryptionType;
11386 }
11387 else
11388 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011389 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 __func__, encryptionType);
11391 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11392 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11393 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11394 }
11395
11396 return 0;
11397}
11398
11399
11400/*
11401 * FUNCTION: wlan_hdd_cfg80211_set_ie
11402 * This function is used to parse WPA/RSN IE's.
11403 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011404int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
11405 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 size_t ie_len
11407 )
11408{
11409 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11410 u8 *genie = ie;
11411 v_U16_t remLen = ie_len;
11412#ifdef FEATURE_WLAN_WAPI
11413 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11414 u16 *tmp;
11415 v_U16_t akmsuiteCount;
11416 int *akmlist;
11417#endif
11418 ENTER();
11419
11420 /* clear previous assocAddIE */
11421 pWextState->assocAddIE.length = 0;
11422 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011423 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011424
11425 while (remLen >= 2)
11426 {
11427 v_U16_t eLen = 0;
11428 v_U8_t elementId;
11429 elementId = *genie++;
11430 eLen = *genie++;
11431 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011432
Arif Hussain6d2a3322013-11-17 19:50:10 -080011433 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011434 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011435
11436 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011437 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011439 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 -070011440 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011441 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 "%s: Invalid WPA IE", __func__);
11443 return -EINVAL;
11444 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011445 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 {
11447 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011448 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011450
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11452 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011453 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11454 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 VOS_ASSERT(0);
11456 return -ENOMEM;
11457 }
11458 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11459 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11460 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011461
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11463 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11464 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11465 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011466 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11467 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11469 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11470 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11471 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11472 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11473 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011474 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011475 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 {
11477 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011478 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011480
Jeff Johnson295189b2012-06-20 16:38:30 -070011481 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11482 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011483 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11484 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011485 VOS_ASSERT(0);
11486 return -ENOMEM;
11487 }
11488 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11489 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11490 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11493 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11494 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011495#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11497 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 /*Consider WFD IE, only for P2P Client */
11499 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11500 {
11501 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011502 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011504
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11506 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011507 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11508 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 VOS_ASSERT(0);
11510 return -ENOMEM;
11511 }
11512 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11513 // WPS IE + P2P IE + WFD IE
11514 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11515 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011516
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11518 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11519 }
11520#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011521 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011522 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011523 HS20_OUI_TYPE_SIZE)) )
11524 {
11525 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011526 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011527 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011528
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011529 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11530 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011531 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11532 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011533 VOS_ASSERT(0);
11534 return -ENOMEM;
11535 }
11536 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11537 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011538
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011539 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11540 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11541 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011542 /* Appending OSEN Information Element in Assiciation Request */
11543 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11544 OSEN_OUI_TYPE_SIZE)) )
11545 {
11546 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11547 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11548 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011549
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011550 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11551 {
11552 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11553 "Need bigger buffer space");
11554 VOS_ASSERT(0);
11555 return -ENOMEM;
11556 }
11557 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11558 pWextState->assocAddIE.length += eLen + 2;
11559
11560 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11561 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11562 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11563 }
11564
11565 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011566 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
11567
11568 /* populating as ADDIE in beacon frames */
11569 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11570 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
11571 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11572 {
11573 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11574 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11575 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11576 {
11577 hddLog(LOGE,
11578 "Coldn't pass "
11579 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11580 }
11581 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11582 else
11583 hddLog(LOGE,
11584 "Could not pass on "
11585 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11586
11587 /* IBSS mode doesn't contain params->proberesp_ies still
11588 beaconIE's need to be populated in probe response frames */
11589 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11590 {
11591 u16 rem_probe_resp_ie_len = eLen + 2;
11592 u8 probe_rsp_ie_len[3] = {0};
11593 u8 counter = 0;
11594
11595 /* Check Probe Resp Length if it is greater then 255 then
11596 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11597 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11598 not able Store More then 255 bytes into One Variable */
11599
11600 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11601 {
11602 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11603 {
11604 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11605 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11606 }
11607 else
11608 {
11609 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11610 rem_probe_resp_ie_len = 0;
11611 }
11612 }
11613
11614 rem_probe_resp_ie_len = 0;
11615
11616 if (probe_rsp_ie_len[0] > 0)
11617 {
11618 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11619 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11620 (tANI_U8*)(genie - 2),
11621 probe_rsp_ie_len[0], NULL,
11622 eANI_BOOLEAN_FALSE)
11623 == eHAL_STATUS_FAILURE)
11624 {
11625 hddLog(LOGE,
11626 "Could not pass"
11627 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11628 }
11629 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11630 }
11631
11632 if (probe_rsp_ie_len[1] > 0)
11633 {
11634 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11635 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11636 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11637 probe_rsp_ie_len[1], NULL,
11638 eANI_BOOLEAN_FALSE)
11639 == eHAL_STATUS_FAILURE)
11640 {
11641 hddLog(LOGE,
11642 "Could not pass"
11643 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11644 }
11645 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11646 }
11647
11648 if (probe_rsp_ie_len[2] > 0)
11649 {
11650 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11651 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11652 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11653 probe_rsp_ie_len[2], NULL,
11654 eANI_BOOLEAN_FALSE)
11655 == eHAL_STATUS_FAILURE)
11656 {
11657 hddLog(LOGE,
11658 "Could not pass"
11659 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11660 }
11661 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11662 }
11663
11664 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11665 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11666 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11667 {
11668 hddLog(LOGE,
11669 "Could not pass"
11670 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11671 }
11672 }
11673 else
11674 {
11675 // Reset WNI_CFG_PROBE_RSP Flags
11676 wlan_hdd_reset_prob_rspies(pAdapter);
11677
11678 hddLog(VOS_TRACE_LEVEL_INFO,
11679 "%s: No Probe Response IE received in set beacon",
11680 __func__);
11681 }
11682 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011683 break;
11684 case DOT11F_EID_RSN:
11685 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11686 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11687 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11688 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11689 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11690 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011691
11692 /* Appending Extended Capabilities with Interworking bit set
11693 * in Assoc Req.
11694 *
11695 * In assoc req this EXT Cap will only be taken into account if
11696 * interworkingService bit is set to 1. Currently
11697 * driver is only interested in interworkingService capability
11698 * from supplicant. If in future any other EXT Cap info is
11699 * required from supplicat, it needs to be handled while
11700 * sending Assoc Req in LIM.
11701 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011702 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011703 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011704 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011705 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011706 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011707
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011708 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11709 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011710 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11711 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011712 VOS_ASSERT(0);
11713 return -ENOMEM;
11714 }
11715 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11716 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011717
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011718 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11719 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11720 break;
11721 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011722#ifdef FEATURE_WLAN_WAPI
11723 case WLAN_EID_WAPI:
11724 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011725 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 pAdapter->wapi_info.nWapiMode);
11727 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011728 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 akmsuiteCount = WPA_GET_LE16(tmp);
11730 tmp = tmp + 1;
11731 akmlist = (int *)(tmp);
11732 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11733 {
11734 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11735 }
11736 else
11737 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011738 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 VOS_ASSERT(0);
11740 return -EINVAL;
11741 }
11742
11743 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11744 {
11745 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011746 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011752 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11754 }
11755 break;
11756#endif
11757 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011760 /* when Unknown IE is received we should break and continue
11761 * to the next IE in the buffer instead we were returning
11762 * so changing this to break */
11763 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 }
11765 genie += eLen;
11766 remLen -= eLen;
11767 }
11768 EXIT();
11769 return 0;
11770}
11771
11772/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011773 * FUNCTION: hdd_isWPAIEPresent
11774 * Parse the received IE to find the WPA IE
11775 *
11776 */
11777static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11778{
11779 v_U8_t eLen = 0;
11780 v_U16_t remLen = ie_len;
11781 v_U8_t elementId = 0;
11782
11783 while (remLen >= 2)
11784 {
11785 elementId = *ie++;
11786 eLen = *ie++;
11787 remLen -= 2;
11788 if (eLen > remLen)
11789 {
11790 hddLog(VOS_TRACE_LEVEL_ERROR,
11791 "%s: IE length is wrong %d", __func__, eLen);
11792 return FALSE;
11793 }
11794 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11795 {
11796 /* OUI - 0x00 0X50 0XF2
11797 WPA Information Element - 0x01
11798 WPA version - 0x01*/
11799 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11800 return TRUE;
11801 }
11802 ie += eLen;
11803 remLen -= eLen;
11804 }
11805 return FALSE;
11806}
11807
11808/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011809 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011810 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011811 * parameters during connect operation.
11812 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011813int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 struct cfg80211_connect_params *req
11815 )
11816{
11817 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011818 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 ENTER();
11820
11821 /*set wpa version*/
11822 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11823
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011824 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011826 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 {
11828 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11829 }
11830 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11831 {
11832 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11833 }
11834 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011835
11836 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 pWextState->wpaVersion);
11838
11839 /*set authentication type*/
11840 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11841
11842 if (0 > status)
11843 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011844 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 "%s: failed to set authentication type ", __func__);
11846 return status;
11847 }
11848
11849 /*set key mgmt type*/
11850 if (req->crypto.n_akm_suites)
11851 {
11852 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11853 if (0 > status)
11854 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 __func__);
11857 return status;
11858 }
11859 }
11860
11861 /*set pairwise cipher type*/
11862 if (req->crypto.n_ciphers_pairwise)
11863 {
11864 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11865 req->crypto.ciphers_pairwise[0], true);
11866 if (0 > status)
11867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011868 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 "%s: failed to set unicast cipher type", __func__);
11870 return status;
11871 }
11872 }
11873 else
11874 {
11875 /*Reset previous cipher suite to none*/
11876 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11877 if (0 > status)
11878 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011879 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 "%s: failed to set unicast cipher type", __func__);
11881 return status;
11882 }
11883 }
11884
11885 /*set group cipher type*/
11886 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11887 false);
11888
11889 if (0 > status)
11890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011891 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 __func__);
11893 return status;
11894 }
11895
Chet Lanctot186b5732013-03-18 10:26:30 -070011896#ifdef WLAN_FEATURE_11W
11897 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11898#endif
11899
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11901 if (req->ie_len)
11902 {
11903 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11904 if ( 0 > status)
11905 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011907 __func__);
11908 return status;
11909 }
11910 }
11911
11912 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011913 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011914 {
11915 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11916 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11917 )
11918 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011919 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11921 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011922 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011923 __func__);
11924 return -EOPNOTSUPP;
11925 }
11926 else
11927 {
11928 u8 key_len = req->key_len;
11929 u8 key_idx = req->key_idx;
11930
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 && (CSR_MAX_NUM_KEY > key_idx)
11933 )
11934 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011935 hddLog(VOS_TRACE_LEVEL_INFO,
11936 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 __func__, key_idx, key_len);
11938 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011939 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011941 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011942 (u8)key_len;
11943 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11944 }
11945 }
11946 }
11947 }
11948
11949 return status;
11950}
11951
11952/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011953 * FUNCTION: wlan_hdd_try_disconnect
11954 * This function is used to disconnect from previous
11955 * connection
11956 */
11957static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11958{
11959 long ret = 0;
11960 hdd_station_ctx_t *pHddStaCtx;
11961 eMib_dot11DesiredBssType connectedBssType;
11962
11963 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11964
11965 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11966
11967 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11968 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11969 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11970 {
11971 /* Issue disconnect to CSR */
11972 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11973 if( eHAL_STATUS_SUCCESS ==
11974 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11975 pAdapter->sessionId,
11976 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11977 {
11978 ret = wait_for_completion_interruptible_timeout(
11979 &pAdapter->disconnect_comp_var,
11980 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11981 if (0 >= ret)
11982 {
11983 hddLog(LOGE, FL("Failed to receive disconnect event"));
11984 return -EALREADY;
11985 }
11986 }
11987 }
11988 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11989 {
11990 ret = wait_for_completion_interruptible_timeout(
11991 &pAdapter->disconnect_comp_var,
11992 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11993 if (0 >= ret)
11994 {
11995 hddLog(LOGE, FL("Failed to receive disconnect event"));
11996 return -EALREADY;
11997 }
11998 }
11999
12000 return 0;
12001}
12002
12003/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012004 * FUNCTION: __wlan_hdd_cfg80211_connect
12005 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012007static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 struct net_device *ndev,
12009 struct cfg80211_connect_params *req
12010 )
12011{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012012 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012013 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012014 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012015 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012016
12017 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012018
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012019 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12020 TRACE_CODE_HDD_CFG80211_CONNECT,
12021 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012022 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012023 "%s: device_mode = %s (%d)", __func__,
12024 hdd_device_modetoString(pAdapter->device_mode),
12025 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012026
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012027 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012028 if (!pHddCtx)
12029 {
12030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12031 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012032 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012033 }
12034
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012035 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012036 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012038 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012039 }
12040
Agarwal Ashish51325b52014-06-16 16:50:49 +053012041 if (vos_max_concurrent_connections_reached()) {
12042 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12043 return -ECONNREFUSED;
12044 }
12045
Jeff Johnson295189b2012-06-20 16:38:30 -070012046#ifdef WLAN_BTAMP_FEATURE
12047 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012048 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012049 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012050 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012051 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012052 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012053 }
12054#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012055
12056 //If Device Mode is Station Concurrent Sessions Exit BMps
12057 //P2P Mode will be taken care in Open/close adapter
12058 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012059 (vos_concurrent_open_sessions_running())) {
12060 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12061 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012062 }
12063
12064 /*Try disconnecting if already in connected state*/
12065 status = wlan_hdd_try_disconnect(pAdapter);
12066 if ( 0 > status)
12067 {
12068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12069 " connection"));
12070 return -EALREADY;
12071 }
12072
Jeff Johnson295189b2012-06-20 16:38:30 -070012073 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012074 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012075
12076 if ( 0 > status)
12077 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012079 __func__);
12080 return status;
12081 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012082 if ( req->channel )
12083 {
12084 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12085 req->ssid_len, req->bssid,
12086 req->channel->hw_value);
12087 }
12088 else
12089 {
12090 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012091 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012092 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012093
Sushant Kaushikd7083982015-03-18 14:33:24 +053012094 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012095 {
12096 //ReEnable BMPS if disabled
12097 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12098 (NULL != pHddCtx))
12099 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012100 if (pHddCtx->hdd_wlan_suspended)
12101 {
12102 hdd_set_pwrparams(pHddCtx);
12103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 //ReEnable Bmps and Imps back
12105 hdd_enable_bmps_imps(pHddCtx);
12106 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012108 return status;
12109 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012110 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012111 EXIT();
12112 return status;
12113}
12114
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012115static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12116 struct net_device *ndev,
12117 struct cfg80211_connect_params *req)
12118{
12119 int ret;
12120 vos_ssr_protect(__func__);
12121 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12122 vos_ssr_unprotect(__func__);
12123
12124 return ret;
12125}
Jeff Johnson295189b2012-06-20 16:38:30 -070012126
12127/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012128 * FUNCTION: wlan_hdd_disconnect
12129 * This function is used to issue a disconnect request to SME
12130 */
12131int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12132{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012133 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012134 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012135 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012136 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012138 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012139
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012140 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012141 if (0 != status)
12142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012143 return status;
12144 }
12145
12146 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012147
Agarwal Ashish47d18112014-08-04 19:55:07 +053012148 /* Need to apply spin lock before decreasing active sessions
12149 * as there can be chance for double decrement if context switch
12150 * Calls hdd_DisConnectHandler.
12151 */
12152
12153 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012154 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12155 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012156 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12157 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012158 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12159 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012160
Abhishek Singhf4669da2014-05-26 15:07:49 +053012161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012162 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12163
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012164 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012165
Mihir Shete182a0b22014-08-18 16:08:48 +053012166 /*
12167 * stop tx queues before deleting STA/BSS context from the firmware.
12168 * tx has to be disabled because the firmware can get busy dropping
12169 * the tx frames after BSS/STA has been deleted and will not send
12170 * back a response resulting in WDI timeout
12171 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012172 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012173 netif_tx_disable(pAdapter->dev);
12174 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012175
Mihir Shete182a0b22014-08-18 16:08:48 +053012176 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012177 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12178 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012179 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12180 {
12181 hddLog(VOS_TRACE_LEVEL_INFO,
12182 FL("status = %d, already disconnected"),
12183 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012184
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012185 }
12186 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012187 {
12188 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012189 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012190 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012191 result = -EINVAL;
12192 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012193 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012194 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012195 &pAdapter->disconnect_comp_var,
12196 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012197 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012198 {
12199 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012200 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012201 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012202 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012203 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012204 {
12205 hddLog(VOS_TRACE_LEVEL_ERROR,
12206 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012207 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012208 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012209disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12211 FL("Set HDD connState to eConnectionState_NotConnected"));
12212 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12213
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012214 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012215 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012216}
12217
12218
12219/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012220 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 * This function is used to issue a disconnect request to SME
12222 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012223static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 struct net_device *dev,
12225 u16 reason
12226 )
12227{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012229 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012230 tCsrRoamProfile *pRoamProfile;
12231 hdd_station_ctx_t *pHddStaCtx;
12232 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012233#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012234 tANI_U8 staIdx;
12235#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012236
Jeff Johnson295189b2012-06-20 16:38:30 -070012237 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012238
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012239 if (!pAdapter) {
12240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12241 return -EINVAL;
12242 }
12243
12244 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12245 if (!pHddStaCtx) {
12246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12247 return -EINVAL;
12248 }
12249
12250 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12251 status = wlan_hdd_validate_context(pHddCtx);
12252 if (0 != status)
12253 {
12254 return status;
12255 }
12256
12257 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12258
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012259 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12260 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12261 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12263 __func__, hdd_device_modetoString(pAdapter->device_mode),
12264 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012265
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012266 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12267 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012268
Jeff Johnson295189b2012-06-20 16:38:30 -070012269 if (NULL != pRoamProfile)
12270 {
12271 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012272 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12273 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012275 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012277 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 switch(reason)
12279 {
12280 case WLAN_REASON_MIC_FAILURE:
12281 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12282 break;
12283
12284 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12285 case WLAN_REASON_DISASSOC_AP_BUSY:
12286 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12287 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12288 break;
12289
12290 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12291 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012292 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12294 break;
12295
Jeff Johnson295189b2012-06-20 16:38:30 -070012296 default:
12297 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12298 break;
12299 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012300 pScanInfo = &pHddCtx->scan_info;
12301 if (pScanInfo->mScanPending)
12302 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012303 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012304 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012305 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012306 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012307 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012308
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012309#ifdef FEATURE_WLAN_TDLS
12310 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012311 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012312 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012313 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12314 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012315 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012316 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012317 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012319 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012320 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012321 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012322 status = sme_DeleteTdlsPeerSta(
12323 WLAN_HDD_GET_HAL_CTX(pAdapter),
12324 pAdapter->sessionId,
12325 mac);
12326 if (status != eHAL_STATUS_SUCCESS) {
12327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12328 return -EPERM;
12329 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012330 }
12331 }
12332#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012333 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012334 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12335 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012336 {
12337 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012338 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012339 __func__, (int)status );
12340 return -EINVAL;
12341 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012342 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012343 else
12344 {
12345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12346 "called while in %d state", __func__,
12347 pHddStaCtx->conn_info.connState);
12348 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 }
12350 else
12351 {
12352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12353 }
12354
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012355 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 return status;
12357}
12358
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012359static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12360 struct net_device *dev,
12361 u16 reason
12362 )
12363{
12364 int ret;
12365 vos_ssr_protect(__func__);
12366 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12367 vos_ssr_unprotect(__func__);
12368
12369 return ret;
12370}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012371
Jeff Johnson295189b2012-06-20 16:38:30 -070012372/*
12373 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012374 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 * settings in IBSS mode.
12376 */
12377static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012378 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012379 struct cfg80211_ibss_params *params
12380 )
12381{
12382 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012383 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012384 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12385 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012386
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 ENTER();
12388
12389 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012390 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012391
12392 if (params->ie_len && ( NULL != params->ie) )
12393 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012394 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12395 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012396 {
12397 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12398 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12399 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012400 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012401 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012402 tDot11fIEWPA dot11WPAIE;
12403 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012404 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012405
Wilson Yang00256342013-10-10 23:13:38 -070012406 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012407 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12408 params->ie_len, DOT11F_EID_WPA);
12409 if ( NULL != ie )
12410 {
12411 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12412 // Unpack the WPA IE
12413 //Skip past the EID byte and length byte - and four byte WiFi OUI
12414 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12415 &ie[2+4],
12416 ie[1] - 4,
12417 &dot11WPAIE);
12418 /*Extract the multicast cipher, the encType for unicast
12419 cipher for wpa-none is none*/
12420 encryptionType =
12421 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12422 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012424
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12426
12427 if (0 > status)
12428 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 __func__);
12431 return status;
12432 }
12433 }
12434
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012435 pWextState->roamProfile.AuthType.authType[0] =
12436 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012437 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12438
12439 if (params->privacy)
12440 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012441 /* Security enabled IBSS, At this time there is no information available
12442 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012444 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012445 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012446 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012447 *enable privacy bit in beacons */
12448
12449 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12450 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012451 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12452 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012453 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12454 pWextState->roamProfile.EncryptionType.numEntries = 1;
12455 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 return status;
12457}
12458
12459/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012460 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012461 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012462 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012463static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 struct net_device *dev,
12465 struct cfg80211_ibss_params *params
12466 )
12467{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012469 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12470 tCsrRoamProfile *pRoamProfile;
12471 int status;
krunal sonie9002db2013-11-25 14:24:17 -080012472 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012473 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12474 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012475
12476 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012477
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012478 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12479 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12480 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012481 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012482 "%s: device_mode = %s (%d)", __func__,
12483 hdd_device_modetoString(pAdapter->device_mode),
12484 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012485
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012486 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012487 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012489 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 }
12491
12492 if (NULL == pWextState)
12493 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012494 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012495 __func__);
12496 return -EIO;
12497 }
12498
Agarwal Ashish51325b52014-06-16 16:50:49 +053012499 if (vos_max_concurrent_connections_reached()) {
12500 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12501 return -ECONNREFUSED;
12502 }
12503
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012504 /*Try disconnecting if already in connected state*/
12505 status = wlan_hdd_try_disconnect(pAdapter);
12506 if ( 0 > status)
12507 {
12508 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12509 " IBSS connection"));
12510 return -EALREADY;
12511 }
12512
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 pRoamProfile = &pWextState->roamProfile;
12514
12515 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12516 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012517 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012518 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012519 return -EINVAL;
12520 }
12521
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012522 /* BSSID is provided by upper layers hence no need to AUTO generate */
12523 if (NULL != params->bssid) {
12524 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12525 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12526 hddLog (VOS_TRACE_LEVEL_ERROR,
12527 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12528 return -EIO;
12529 }
12530 }
krunal sonie9002db2013-11-25 14:24:17 -080012531 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12532 {
12533 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12534 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12535 {
12536 hddLog (VOS_TRACE_LEVEL_ERROR,
12537 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12538 return -EIO;
12539 }
Sachin Ahuja46ff4912015-03-23 22:48:43 +053012540 params->bssid = vos_mem_malloc(VOS_MAC_ADDR_SIZE);
krunal sonie9002db2013-11-25 14:24:17 -080012541 if (!params->bssid)
12542 {
12543 hddLog (VOS_TRACE_LEVEL_ERROR,
12544 "%s:Failed memory allocation", __func__);
12545 return -EIO;
12546 }
12547 vos_mem_copy((v_U8_t *)params->bssid,
12548 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
12549 VOS_MAC_ADDR_SIZE);
12550 alloc_bssid = VOS_TRUE;
12551 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012552
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012554 if (NULL !=
12555#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12556 params->chandef.chan)
12557#else
12558 params->channel)
12559#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 {
12561 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012562 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12563 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12564 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12565 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012566
12567 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012568 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012569 ieee80211_frequency_to_channel(
12570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12571 params->chandef.chan->center_freq);
12572#else
12573 params->channel->center_freq);
12574#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012575
12576 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12577 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12580 __func__);
12581 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012582 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012583
12584 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012586 if (channelNum == validChan[indx])
12587 {
12588 break;
12589 }
12590 }
12591 if (indx >= numChans)
12592 {
12593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012594 __func__, channelNum);
12595 return -EINVAL;
12596 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012597 /* Set the Operational Channel */
12598 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12599 channelNum);
12600 pRoamProfile->ChannelInfo.numOfChannels = 1;
12601 pHddStaCtx->conn_info.operationChannel = channelNum;
12602 pRoamProfile->ChannelInfo.ChannelList =
12603 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 }
12605
12606 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012607 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 if (status < 0)
12609 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 __func__);
12612 return status;
12613 }
12614
12615 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012616 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012617 params->ssid_len, params->bssid,
12618 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012619
12620 if (0 > status)
12621 {
12622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12623 return status;
12624 }
12625
krunal sonie9002db2013-11-25 14:24:17 -080012626 if (NULL != params->bssid &&
12627 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12628 alloc_bssid == VOS_TRUE)
12629 {
12630 vos_mem_free(params->bssid);
12631 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012632 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 return 0;
12634}
12635
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012636static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12637 struct net_device *dev,
12638 struct cfg80211_ibss_params *params
12639 )
12640{
12641 int ret = 0;
12642
12643 vos_ssr_protect(__func__);
12644 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12645 vos_ssr_unprotect(__func__);
12646
12647 return ret;
12648}
12649
Jeff Johnson295189b2012-06-20 16:38:30 -070012650/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012651 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012652 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012653 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012654static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012655 struct net_device *dev
12656 )
12657{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012659 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12660 tCsrRoamProfile *pRoamProfile;
12661 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012662 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012663
12664 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012665
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012666 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12667 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12668 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012669 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012670 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012671 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012672 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012673 }
12674
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012675 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12676 hdd_device_modetoString(pAdapter->device_mode),
12677 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 if (NULL == pWextState)
12679 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012680 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 __func__);
12682 return -EIO;
12683 }
12684
12685 pRoamProfile = &pWextState->roamProfile;
12686
12687 /* Issue disconnect only if interface type is set to IBSS */
12688 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12689 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012690 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 __func__);
12692 return -EINVAL;
12693 }
12694
12695 /* Issue Disconnect request */
12696 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12697 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12698 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12699
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012700 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 return 0;
12702}
12703
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012704static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12705 struct net_device *dev
12706 )
12707{
12708 int ret = 0;
12709
12710 vos_ssr_protect(__func__);
12711 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12712 vos_ssr_unprotect(__func__);
12713
12714 return ret;
12715}
12716
Jeff Johnson295189b2012-06-20 16:38:30 -070012717/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012718 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 * This function is used to set the phy parameters
12720 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12721 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012722static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012723 u32 changed)
12724{
12725 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12726 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012727 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012728
12729 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012730
12731 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012732 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12733 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012734
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012735 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012736 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012737 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012738 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012739 }
12740
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12742 {
12743 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12744 WNI_CFG_RTS_THRESHOLD_STAMAX :
12745 wiphy->rts_threshold;
12746
12747 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012748 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012749 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012750 hddLog(VOS_TRACE_LEVEL_ERROR,
12751 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012752 __func__, rts_threshold);
12753 return -EINVAL;
12754 }
12755
12756 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12757 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012758 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012759 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012760 hddLog(VOS_TRACE_LEVEL_ERROR,
12761 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012762 __func__, rts_threshold);
12763 return -EIO;
12764 }
12765
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012766 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012767 rts_threshold);
12768 }
12769
12770 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12771 {
12772 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12773 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12774 wiphy->frag_threshold;
12775
12776 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012777 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012778 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012779 hddLog(VOS_TRACE_LEVEL_ERROR,
12780 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012781 frag_threshold);
12782 return -EINVAL;
12783 }
12784
12785 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12786 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012787 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012789 hddLog(VOS_TRACE_LEVEL_ERROR,
12790 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012791 __func__, frag_threshold);
12792 return -EIO;
12793 }
12794
12795 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12796 frag_threshold);
12797 }
12798
12799 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12800 || (changed & WIPHY_PARAM_RETRY_LONG))
12801 {
12802 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12803 wiphy->retry_short :
12804 wiphy->retry_long;
12805
12806 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12807 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012809 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 __func__, retry_value);
12811 return -EINVAL;
12812 }
12813
12814 if (changed & WIPHY_PARAM_RETRY_SHORT)
12815 {
12816 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12817 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012818 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012819 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012820 hddLog(VOS_TRACE_LEVEL_ERROR,
12821 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012822 __func__, retry_value);
12823 return -EIO;
12824 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012825 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 __func__, retry_value);
12827 }
12828 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12829 {
12830 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12831 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012832 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012833 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012834 hddLog(VOS_TRACE_LEVEL_ERROR,
12835 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012836 __func__, retry_value);
12837 return -EIO;
12838 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012839 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012840 __func__, retry_value);
12841 }
12842 }
12843
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012844 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 return 0;
12846}
12847
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012848static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12849 u32 changed)
12850{
12851 int ret;
12852
12853 vos_ssr_protect(__func__);
12854 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12855 vos_ssr_unprotect(__func__);
12856
12857 return ret;
12858}
12859
Jeff Johnson295189b2012-06-20 16:38:30 -070012860/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012861 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012862 * This function is used to set the txpower
12863 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012864static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012865#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12866 struct wireless_dev *wdev,
12867#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012868#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012869 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012870#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012871 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012872#endif
12873 int dbm)
12874{
12875 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012876 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12878 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012879 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012880
12881 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012882
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012883 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12884 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12885 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012886 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012887 if (0 != status)
12888 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012889 return status;
12890 }
12891
12892 hHal = pHddCtx->hHal;
12893
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012894 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12895 dbm, ccmCfgSetCallback,
12896 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012897 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012898 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012899 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12900 return -EIO;
12901 }
12902
12903 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12904 dbm);
12905
12906 switch(type)
12907 {
12908 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12909 /* Fall through */
12910 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12911 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12914 __func__);
12915 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 }
12917 break;
12918 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012920 __func__);
12921 return -EOPNOTSUPP;
12922 break;
12923 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012924 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12925 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012926 return -EIO;
12927 }
12928
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012929 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 return 0;
12931}
12932
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012933static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12934#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12935 struct wireless_dev *wdev,
12936#endif
12937#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12938 enum tx_power_setting type,
12939#else
12940 enum nl80211_tx_power_setting type,
12941#endif
12942 int dbm)
12943{
12944 int ret;
12945 vos_ssr_protect(__func__);
12946 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12947#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12948 wdev,
12949#endif
12950#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12951 type,
12952#else
12953 type,
12954#endif
12955 dbm);
12956 vos_ssr_unprotect(__func__);
12957
12958 return ret;
12959}
12960
Jeff Johnson295189b2012-06-20 16:38:30 -070012961/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012962 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012963 * This function is used to read the txpower
12964 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012965static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012966#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12967 struct wireless_dev *wdev,
12968#endif
12969 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012970{
12971
12972 hdd_adapter_t *pAdapter;
12973 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012974 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012975
Jeff Johnsone7245742012-09-05 17:12:55 -070012976 ENTER();
12977
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012978 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012979 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012980 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012981 *dbm = 0;
12982 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012983 }
12984
Jeff Johnson295189b2012-06-20 16:38:30 -070012985 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12986 if (NULL == pAdapter)
12987 {
12988 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12989 return -ENOENT;
12990 }
12991
12992 wlan_hdd_get_classAstats(pAdapter);
12993 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12994
Jeff Johnsone7245742012-09-05 17:12:55 -070012995 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012996 return 0;
12997}
12998
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012999static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13000#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13001 struct wireless_dev *wdev,
13002#endif
13003 int *dbm)
13004{
13005 int ret;
13006
13007 vos_ssr_protect(__func__);
13008 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13009#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13010 wdev,
13011#endif
13012 dbm);
13013 vos_ssr_unprotect(__func__);
13014
13015 return ret;
13016}
13017
13018
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013019static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070013020 u8* mac, struct station_info *sinfo)
13021{
13022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13023 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13024 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013025 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013026
13027 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13028 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013029
13030 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13031 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13032 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13033 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13034 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13035 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13036 tANI_U16 maxRate = 0;
13037 tANI_U16 myRate;
13038 tANI_U16 currentRate = 0;
13039 tANI_U8 maxSpeedMCS = 0;
13040 tANI_U8 maxMCSIdx = 0;
13041 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013042 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013043 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013044 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013045
Leo Chang6f8870f2013-03-26 18:11:36 -070013046#ifdef WLAN_FEATURE_11AC
13047 tANI_U32 vht_mcs_map;
13048 eDataRate11ACMaxMcs vhtMaxMcs;
13049#endif /* WLAN_FEATURE_11AC */
13050
Jeff Johnsone7245742012-09-05 17:12:55 -070013051 ENTER();
13052
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13054 (0 == ssidlen))
13055 {
13056 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13057 " Invalid ssidlen, %d", __func__, ssidlen);
13058 /*To keep GUI happy*/
13059 return 0;
13060 }
13061
Mukul Sharma811205f2014-07-09 21:07:30 +053013062 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13063 {
13064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13065 "%s: Roaming in progress, so unable to proceed this request", __func__);
13066 return 0;
13067 }
13068
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013069 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013070 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013071 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013072 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013073 }
13074
Jeff Johnson295189b2012-06-20 16:38:30 -070013075
Kiet Lam3b17fc82013-09-27 05:24:08 +053013076 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13077 sinfo->filled |= STATION_INFO_SIGNAL;
13078
c_hpothu09f19542014-05-30 21:53:31 +053013079 wlan_hdd_get_station_stats(pAdapter);
13080 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13081
13082 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013083 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13084 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013085 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013086 {
13087 rate_flags = pAdapter->maxRateFlags;
13088 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013089
Jeff Johnson295189b2012-06-20 16:38:30 -070013090 //convert to the UI units of 100kbps
13091 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13092
13093#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013094 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 -070013095 sinfo->signal,
13096 pCfg->reportMaxLinkSpeed,
13097 myRate,
13098 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013099 (int) pCfg->linkSpeedRssiMid,
13100 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013101 (int) rate_flags,
13102 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013103#endif //LINKSPEED_DEBUG_ENABLED
13104
13105 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13106 {
13107 // we do not want to necessarily report the current speed
13108 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13109 {
13110 // report the max possible speed
13111 rssidx = 0;
13112 }
13113 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13114 {
13115 // report the max possible speed with RSSI scaling
13116 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13117 {
13118 // report the max possible speed
13119 rssidx = 0;
13120 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013121 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 {
13123 // report middle speed
13124 rssidx = 1;
13125 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013126 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13127 {
13128 // report middle speed
13129 rssidx = 2;
13130 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013131 else
13132 {
13133 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013134 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013135 }
13136 }
13137 else
13138 {
13139 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13140 hddLog(VOS_TRACE_LEVEL_ERROR,
13141 "%s: Invalid value for reportMaxLinkSpeed: %u",
13142 __func__, pCfg->reportMaxLinkSpeed);
13143 rssidx = 0;
13144 }
13145
13146 maxRate = 0;
13147
13148 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013149 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13150 OperationalRates, &ORLeng))
13151 {
13152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13153 /*To keep GUI happy*/
13154 return 0;
13155 }
13156
Jeff Johnson295189b2012-06-20 16:38:30 -070013157 for (i = 0; i < ORLeng; i++)
13158 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013159 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013160 {
13161 /* Validate Rate Set */
13162 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13163 {
13164 currentRate = supported_data_rate[j].supported_rate[rssidx];
13165 break;
13166 }
13167 }
13168 /* Update MAX rate */
13169 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13170 }
13171
13172 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013173 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13174 ExtendedRates, &ERLeng))
13175 {
13176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13177 /*To keep GUI happy*/
13178 return 0;
13179 }
13180
Jeff Johnson295189b2012-06-20 16:38:30 -070013181 for (i = 0; i < ERLeng; i++)
13182 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013183 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013184 {
13185 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13186 {
13187 currentRate = supported_data_rate[j].supported_rate[rssidx];
13188 break;
13189 }
13190 }
13191 /* Update MAX rate */
13192 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13193 }
c_hpothu79aab322014-07-14 21:11:01 +053013194
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013195 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013196 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013197 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013198 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013199 {
c_hpothu79aab322014-07-14 21:11:01 +053013200 if (rate_flags & eHAL_TX_RATE_VHT80)
13201 mode = 2;
13202 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13203 mode = 1;
13204 else
13205 mode = 0;
13206
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013207 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13208 MCSRates, &MCSLeng))
13209 {
13210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13211 /*To keep GUI happy*/
13212 return 0;
13213 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013214 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013215#ifdef WLAN_FEATURE_11AC
13216 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013217 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013218 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013219 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013220 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013221 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013223 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013225 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013227 maxMCSIdx = 7;
13228 }
13229 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13230 {
13231 maxMCSIdx = 8;
13232 }
13233 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13234 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013235 //VHT20 is supporting 0~8
13236 if (rate_flags & eHAL_TX_RATE_VHT20)
13237 maxMCSIdx = 8;
13238 else
13239 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013240 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013241
c_hpothu79aab322014-07-14 21:11:01 +053013242 if (0 != rssidx)/*check for scaled */
13243 {
13244 //get middle rate MCS index if rssi=1/2
13245 for (i=0; i <= maxMCSIdx; i++)
13246 {
13247 if (sinfo->signal <= rssiMcsTbl[mode][i])
13248 {
13249 maxMCSIdx = i;
13250 break;
13251 }
13252 }
13253 }
13254
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013255 if (rate_flags & eHAL_TX_RATE_VHT80)
13256 {
13257 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13258 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13259 }
13260 else if (rate_flags & eHAL_TX_RATE_VHT40)
13261 {
13262 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13263 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13264 }
13265 else if (rate_flags & eHAL_TX_RATE_VHT20)
13266 {
13267 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13268 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13269 }
13270
Leo Chang6f8870f2013-03-26 18:11:36 -070013271 maxSpeedMCS = 1;
13272 if (currentRate > maxRate)
13273 {
13274 maxRate = currentRate;
13275 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013276
Leo Chang6f8870f2013-03-26 18:11:36 -070013277 }
13278 else
13279#endif /* WLAN_FEATURE_11AC */
13280 {
13281 if (rate_flags & eHAL_TX_RATE_HT40)
13282 {
13283 rateFlag |= 1;
13284 }
13285 if (rate_flags & eHAL_TX_RATE_SGI)
13286 {
13287 rateFlag |= 2;
13288 }
13289
Girish Gowli01abcee2014-07-31 20:18:55 +053013290 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013291 if (rssidx == 1 || rssidx == 2)
13292 {
13293 //get middle rate MCS index if rssi=1/2
13294 for (i=0; i <= 7; i++)
13295 {
13296 if (sinfo->signal <= rssiMcsTbl[mode][i])
13297 {
13298 temp = i+1;
13299 break;
13300 }
13301 }
13302 }
c_hpothu79aab322014-07-14 21:11:01 +053013303
13304 for (i = 0; i < MCSLeng; i++)
13305 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013306 for (j = 0; j < temp; j++)
13307 {
13308 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13309 {
13310 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
13311 break;
13312 }
13313 }
13314 if ((j < temp) && (currentRate > maxRate))
13315 {
13316 maxRate = currentRate;
13317 maxSpeedMCS = 1;
13318 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
13319 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013320 }
13321 }
13322 }
13323
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013324 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13325 {
13326 maxRate = myRate;
13327 maxSpeedMCS = 1;
13328 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13329 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013330 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013331 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013332 {
13333 maxRate = myRate;
13334 if (rate_flags & eHAL_TX_RATE_LEGACY)
13335 {
13336 maxSpeedMCS = 0;
13337 }
13338 else
13339 {
13340 maxSpeedMCS = 1;
13341 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13342 }
13343 }
13344
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013345 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013346 {
13347 sinfo->txrate.legacy = maxRate;
13348#ifdef LINKSPEED_DEBUG_ENABLED
13349 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13350#endif //LINKSPEED_DEBUG_ENABLED
13351 }
13352 else
13353 {
13354 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013355#ifdef WLAN_FEATURE_11AC
13356 sinfo->txrate.nss = 1;
13357 if (rate_flags & eHAL_TX_RATE_VHT80)
13358 {
13359 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013360 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013361 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013362 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013363 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013364 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13365 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13366 }
13367 else if (rate_flags & eHAL_TX_RATE_VHT20)
13368 {
13369 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13370 }
13371#endif /* WLAN_FEATURE_11AC */
13372 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13373 {
13374 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13375 if (rate_flags & eHAL_TX_RATE_HT40)
13376 {
13377 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13378 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013379 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 if (rate_flags & eHAL_TX_RATE_SGI)
13381 {
13382 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13383 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013384
Jeff Johnson295189b2012-06-20 16:38:30 -070013385#ifdef LINKSPEED_DEBUG_ENABLED
13386 pr_info("Reporting MCS rate %d flags %x\n",
13387 sinfo->txrate.mcs,
13388 sinfo->txrate.flags );
13389#endif //LINKSPEED_DEBUG_ENABLED
13390 }
13391 }
13392 else
13393 {
13394 // report current rate instead of max rate
13395
13396 if (rate_flags & eHAL_TX_RATE_LEGACY)
13397 {
13398 //provide to the UI in units of 100kbps
13399 sinfo->txrate.legacy = myRate;
13400#ifdef LINKSPEED_DEBUG_ENABLED
13401 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13402#endif //LINKSPEED_DEBUG_ENABLED
13403 }
13404 else
13405 {
13406 //must be MCS
13407 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013408#ifdef WLAN_FEATURE_11AC
13409 sinfo->txrate.nss = 1;
13410 if (rate_flags & eHAL_TX_RATE_VHT80)
13411 {
13412 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13413 }
13414 else
13415#endif /* WLAN_FEATURE_11AC */
13416 {
13417 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13418 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013419 if (rate_flags & eHAL_TX_RATE_SGI)
13420 {
13421 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13422 }
13423 if (rate_flags & eHAL_TX_RATE_HT40)
13424 {
13425 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13426 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013427#ifdef WLAN_FEATURE_11AC
13428 else if (rate_flags & eHAL_TX_RATE_VHT80)
13429 {
13430 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13431 }
13432#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013433#ifdef LINKSPEED_DEBUG_ENABLED
13434 pr_info("Reporting actual MCS rate %d flags %x\n",
13435 sinfo->txrate.mcs,
13436 sinfo->txrate.flags );
13437#endif //LINKSPEED_DEBUG_ENABLED
13438 }
13439 }
13440 sinfo->filled |= STATION_INFO_TX_BITRATE;
13441
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013442 sinfo->tx_packets =
13443 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13444 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13445 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13446 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13447
13448 sinfo->tx_retries =
13449 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13450 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13451 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13452 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13453
13454 sinfo->tx_failed =
13455 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13456 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13457 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13458 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13459
13460 sinfo->filled |=
13461 STATION_INFO_TX_PACKETS |
13462 STATION_INFO_TX_RETRIES |
13463 STATION_INFO_TX_FAILED;
13464
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013465 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13466 TRACE_CODE_HDD_CFG80211_GET_STA,
13467 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013468 EXIT();
13469 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013470}
13471
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013472static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13473 u8* mac, struct station_info *sinfo)
13474{
13475 int ret;
13476
13477 vos_ssr_protect(__func__);
13478 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13479 vos_ssr_unprotect(__func__);
13480
13481 return ret;
13482}
13483
13484static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013485 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013486{
13487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013488 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013489 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013490 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013491
Jeff Johnsone7245742012-09-05 17:12:55 -070013492 ENTER();
13493
Jeff Johnson295189b2012-06-20 16:38:30 -070013494 if (NULL == pAdapter)
13495 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 return -ENODEV;
13498 }
13499
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013500 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13501 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13502 pAdapter->sessionId, timeout));
13503
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013504 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013505 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013506 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013507 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013508 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013509 }
13510
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013511 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13512 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13513 (pHddCtx->cfg_ini->fhostArpOffload) &&
13514 (eConnectionState_Associated ==
13515 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13516 {
Amar Singhald53568e2013-09-26 11:03:45 -070013517
13518 hddLog(VOS_TRACE_LEVEL_INFO,
13519 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013520 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013521 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13522 {
13523 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013524 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013525 __func__, vos_status);
13526 }
13527 }
13528
Jeff Johnson295189b2012-06-20 16:38:30 -070013529 /**The get power cmd from the supplicant gets updated by the nl only
13530 *on successful execution of the function call
13531 *we are oppositely mapped w.r.t mode in the driver
13532 **/
13533 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13534
13535 if (VOS_STATUS_E_FAILURE == vos_status)
13536 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13538 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 return -EINVAL;
13540 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013541 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013542 return 0;
13543}
13544
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013545static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13546 struct net_device *dev, bool mode, int timeout)
13547{
13548 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013549
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013550 vos_ssr_protect(__func__);
13551 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13552 vos_ssr_unprotect(__func__);
13553
13554 return ret;
13555}
Jeff Johnson295189b2012-06-20 16:38:30 -070013556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013557static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13558 struct net_device *netdev,
13559 u8 key_index)
13560{
13561 ENTER();
13562 return 0;
13563}
13564
Jeff Johnson295189b2012-06-20 16:38:30 -070013565static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013566 struct net_device *netdev,
13567 u8 key_index)
13568{
13569 int ret;
13570 vos_ssr_protect(__func__);
13571 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13572 vos_ssr_unprotect(__func__);
13573 return ret;
13574}
13575#endif //LINUX_VERSION_CODE
13576
13577#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13578static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13579 struct net_device *dev,
13580 struct ieee80211_txq_params *params)
13581{
13582 ENTER();
13583 return 0;
13584}
13585#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13586static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13587 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013588{
Jeff Johnsone7245742012-09-05 17:12:55 -070013589 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 return 0;
13591}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013592#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013593
13594#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13595static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013596 struct net_device *dev,
13597 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013598{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013599 int ret;
13600
13601 vos_ssr_protect(__func__);
13602 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13603 vos_ssr_unprotect(__func__);
13604 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013605}
13606#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13607static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13608 struct ieee80211_txq_params *params)
13609{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013610 int ret;
13611
13612 vos_ssr_protect(__func__);
13613 ret = __wlan_hdd_set_txq_params(wiphy, params);
13614 vos_ssr_unprotect(__func__);
13615 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013616}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013617#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013618
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013619static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013620 struct net_device *dev,
13621 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013622{
13623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013624 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013625 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013626 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013627 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013628 v_CONTEXT_t pVosContext = NULL;
13629 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013630
Jeff Johnsone7245742012-09-05 17:12:55 -070013631 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013632
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013633 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013635 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013636 return -EINVAL;
13637 }
13638
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013639 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13640 TRACE_CODE_HDD_CFG80211_DEL_STA,
13641 pAdapter->sessionId, pAdapter->device_mode));
13642
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13644 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013645 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013646 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013647 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013648 }
13649
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013652 )
13653 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013654 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13655 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13656 if(pSapCtx == NULL){
13657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13658 FL("psapCtx is NULL"));
13659 return -ENOENT;
13660 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013661 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013662 {
13663 v_U16_t i;
13664 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13665 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013666 if ((pSapCtx->aStaInfo[i].isUsed) &&
13667 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013669 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013670 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013671 ETHER_ADDR_LEN);
13672
Jeff Johnson295189b2012-06-20 16:38:30 -070013673 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013674 "%s: Delete STA with MAC::"
13675 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013676 __func__,
13677 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13678 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013679 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013680 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013681 }
13682 }
13683 }
13684 else
13685 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013686
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013687 vos_status = hdd_softap_GetStaId(pAdapter,
13688 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013689 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13690 {
13691 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013692 "%s: Skip this DEL STA as this is not used::"
13693 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013694 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013695 return -ENOENT;
13696 }
13697
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013698 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013699 {
13700 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013701 "%s: Skip this DEL STA as deauth is in progress::"
13702 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013703 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013704 return -ENOENT;
13705 }
13706
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013707 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013708
Jeff Johnson295189b2012-06-20 16:38:30 -070013709 hddLog(VOS_TRACE_LEVEL_INFO,
13710 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013711 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013713 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013714
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013715 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013716 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13717 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013718 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013719 hddLog(VOS_TRACE_LEVEL_INFO,
13720 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013721 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013722 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013723 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013724 return -ENOENT;
13725 }
13726
Jeff Johnson295189b2012-06-20 16:38:30 -070013727 }
13728 }
13729
13730 EXIT();
13731
13732 return 0;
13733}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013734
13735#ifdef CFG80211_DEL_STA_V2
13736static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13737 struct net_device *dev,
13738 struct station_del_parameters *param)
13739#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013740static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13741 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013742#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013743{
13744 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013745 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013746
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013747 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013748
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013749#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013750 if (NULL == param) {
13751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013752 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013753 return -EINVAL;
13754 }
13755
13756 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13757 param->subtype, &delStaParams);
13758
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013759#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013760 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013761 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013762#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013763 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13764
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013765 vos_ssr_unprotect(__func__);
13766
13767 return ret;
13768}
13769
13770static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013771 struct net_device *dev, u8 *mac, struct station_parameters *params)
13772{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013773 hdd_adapter_t *pAdapter;
13774 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013775 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013776#ifdef FEATURE_WLAN_TDLS
13777 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013778
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013779 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013780
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013781 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13782 if (NULL == pAdapter)
13783 {
13784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13785 "%s: Adapter is NULL",__func__);
13786 return -EINVAL;
13787 }
13788 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13789 status = wlan_hdd_validate_context(pHddCtx);
13790 if (0 != status)
13791 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013792 return status;
13793 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013794
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013795 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13796 TRACE_CODE_HDD_CFG80211_ADD_STA,
13797 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013798 mask = params->sta_flags_mask;
13799
13800 set = params->sta_flags_set;
13801
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013803 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13804 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013805
13806 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13807 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013808 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013809 }
13810 }
13811#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013812 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013813 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013814}
13815
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013816static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13817 struct net_device *dev, u8 *mac, struct station_parameters *params)
13818{
13819 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013820
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013821 vos_ssr_protect(__func__);
13822 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13823 vos_ssr_unprotect(__func__);
13824
13825 return ret;
13826}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013827#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013828
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013829static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013830 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013831{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13833 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013834 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013835 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013836 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013837 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013838
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013839 ENTER();
13840
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013841 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013842 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013843 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013844 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013845 return -EINVAL;
13846 }
13847
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013848 if (!pmksa) {
13849 hddLog(LOGE, FL("pmksa is NULL"));
13850 return -EINVAL;
13851 }
13852
13853 if (!pmksa->bssid || !pmksa->pmkid) {
13854 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13855 pmksa->bssid, pmksa->pmkid);
13856 return -EINVAL;
13857 }
13858
13859 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13860 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13861
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013862 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13863 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013864 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013866 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013867 }
13868
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013869 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013870 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13871
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013872 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13873 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013874
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013875 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013876 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013877 &pmk_id, 1, FALSE);
13878
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013879 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13880 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13881 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013882
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013883 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013884 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013885}
13886
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013887static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13888 struct cfg80211_pmksa *pmksa)
13889{
13890 int ret;
13891
13892 vos_ssr_protect(__func__);
13893 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13894 vos_ssr_unprotect(__func__);
13895
13896 return ret;
13897}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013898
Wilson Yang6507c4e2013-10-01 20:11:19 -070013899
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013900static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013901 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013902{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013903 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13904 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013905 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013906 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013907
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013908 ENTER();
13909
Wilson Yang6507c4e2013-10-01 20:11:19 -070013910 /* Validate pAdapter */
13911 if (NULL == pAdapter)
13912 {
13913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13914 return -EINVAL;
13915 }
13916
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013917 if (!pmksa) {
13918 hddLog(LOGE, FL("pmksa is NULL"));
13919 return -EINVAL;
13920 }
13921
13922 if (!pmksa->bssid) {
13923 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13924 return -EINVAL;
13925 }
13926
Kiet Lam98c46a12014-10-31 15:34:57 -070013927 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13928 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13929
Wilson Yang6507c4e2013-10-01 20:11:19 -070013930 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13931 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013932 if (0 != status)
13933 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013934 return status;
13935 }
13936
13937 /*Retrieve halHandle*/
13938 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13939
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013940 /* Delete the PMKID CSR cache */
13941 if (eHAL_STATUS_SUCCESS !=
13942 sme_RoamDelPMKIDfromCache(halHandle,
13943 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13944 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13945 MAC_ADDR_ARRAY(pmksa->bssid));
13946 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013947 }
13948
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013949 EXIT();
13950 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013951}
13952
Wilson Yang6507c4e2013-10-01 20:11:19 -070013953
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013954static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13955 struct cfg80211_pmksa *pmksa)
13956{
13957 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013958
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013959 vos_ssr_protect(__func__);
13960 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13961 vos_ssr_unprotect(__func__);
13962
13963 return ret;
13964
13965}
13966
13967static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013968{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13970 tHalHandle halHandle;
13971 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013972 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013973
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013974 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070013975
13976 /* Validate pAdapter */
13977 if (NULL == pAdapter)
13978 {
13979 hddLog(VOS_TRACE_LEVEL_ERROR,
13980 "%s: Invalid Adapter" ,__func__);
13981 return -EINVAL;
13982 }
13983
13984 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13985 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070013986 if (0 != status)
13987 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070013988 return status;
13989 }
13990
13991 /*Retrieve halHandle*/
13992 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13993
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013994 /* Flush the PMKID cache in CSR */
13995 if (eHAL_STATUS_SUCCESS !=
13996 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13998 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013999 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014000 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014001 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014002}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014003
14004static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14005{
14006 int ret;
14007
14008 vos_ssr_protect(__func__);
14009 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14010 vos_ssr_unprotect(__func__);
14011
14012 return ret;
14013}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014014#endif
14015
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014016#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014017static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14018 struct net_device *dev,
14019 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014020{
14021 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14022 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014023 hdd_context_t *pHddCtx;
14024 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014025
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014026 ENTER();
14027
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014028 if (NULL == pAdapter)
14029 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014031 return -ENODEV;
14032 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014033 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14034 ret = wlan_hdd_validate_context(pHddCtx);
14035 if (0 != ret)
14036 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014037 return ret;
14038 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014039 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014040 if (NULL == pHddStaCtx)
14041 {
14042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14043 return -EINVAL;
14044 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014045
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14047 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14048 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014049 // Added for debug on reception of Re-assoc Req.
14050 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14051 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014052 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014053 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014054 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014055 }
14056
14057#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014058 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014059 ftie->ie_len);
14060#endif
14061
14062 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014063 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14064 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014065 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014066
14067 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014068 return 0;
14069}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014070
14071static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14072 struct net_device *dev,
14073 struct cfg80211_update_ft_ies_params *ftie)
14074{
14075 int ret;
14076
14077 vos_ssr_protect(__func__);
14078 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14079 vos_ssr_unprotect(__func__);
14080
14081 return ret;
14082}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014083#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014084
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014085#ifdef FEATURE_WLAN_SCAN_PNO
14086
14087void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14088 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14089{
14090 int ret;
14091 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14092 hdd_context_t *pHddCtx;
14093
Nirav Shah80830bf2013-12-31 16:35:12 +053014094 ENTER();
14095
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014096 if (NULL == pAdapter)
14097 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014099 "%s: HDD adapter is Null", __func__);
14100 return ;
14101 }
14102
14103 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14104 if (NULL == pHddCtx)
14105 {
14106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14107 "%s: HDD context is Null!!!", __func__);
14108 return ;
14109 }
14110
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014111 spin_lock(&pHddCtx->schedScan_lock);
14112 if (TRUE == pHddCtx->isWiphySuspended)
14113 {
14114 pHddCtx->isSchedScanUpdatePending = TRUE;
14115 spin_unlock(&pHddCtx->schedScan_lock);
14116 hddLog(VOS_TRACE_LEVEL_INFO,
14117 "%s: Update cfg80211 scan database after it resume", __func__);
14118 return ;
14119 }
14120 spin_unlock(&pHddCtx->schedScan_lock);
14121
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014122 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14123
14124 if (0 > ret)
14125 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14126
14127 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14129 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014130}
14131
14132/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014133 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014134 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014135 */
14136static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14137{
14138 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14139 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014140 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014141 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14142 int status = 0;
14143 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14144
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014145 /* The current firmware design does not allow PNO during any
14146 * active sessions. Hence, determine the active sessions
14147 * and return a failure.
14148 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014149 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14150 {
14151 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014152 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014153
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014154 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14155 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14156 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14157 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14158 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014159 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014160 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014161 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014162 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014163 }
14164 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14165 pAdapterNode = pNext;
14166 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014167 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014168}
14169
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014170void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14171{
14172 hdd_adapter_t *pAdapter = callbackContext;
14173 hdd_context_t *pHddCtx;
14174
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014175 ENTER();
14176
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014177 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14178 {
14179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14180 FL("Invalid adapter or adapter has invalid magic"));
14181 return;
14182 }
14183
14184 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14185 if (0 != wlan_hdd_validate_context(pHddCtx))
14186 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014187 return;
14188 }
14189
c_hpothub53c45d2014-08-18 16:53:14 +053014190 if (VOS_STATUS_SUCCESS != status)
14191 {
14192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014193 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014194 pHddCtx->isPnoEnable = FALSE;
14195 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014196
14197 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14198 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014199 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014200}
14201
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014202/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014203 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14204 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014205 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014206static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014207 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14208{
14209 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014210 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014211 hdd_context_t *pHddCtx;
14212 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014213 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014214 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14215 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014216 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14217 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014218 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014219 hdd_config_t *pConfig = NULL;
14220 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014221
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014222 ENTER();
14223
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014224 if (NULL == pAdapter)
14225 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014227 "%s: HDD adapter is Null", __func__);
14228 return -ENODEV;
14229 }
14230
14231 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014232 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014233
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014234 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014235 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014236 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014237 }
14238
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014239 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014240 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14241 if (NULL == hHal)
14242 {
14243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14244 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014245 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014246 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014247 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014248 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014249 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014250 {
14251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14252 "%s: aborting the existing scan is unsuccessfull", __func__);
14253 return -EBUSY;
14254 }
14255
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014256 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014257 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014259 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014260 return -EBUSY;
14261 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014262
c_hpothu37f21312014-04-09 21:49:54 +053014263 if (TRUE == pHddCtx->isPnoEnable)
14264 {
14265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14266 FL("already PNO is enabled"));
14267 return -EBUSY;
14268 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014269
14270 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14271 {
14272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14273 "%s: abort ROC failed ", __func__);
14274 return -EBUSY;
14275 }
14276
c_hpothu37f21312014-04-09 21:49:54 +053014277 pHddCtx->isPnoEnable = TRUE;
14278
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014279 pnoRequest.enable = 1; /*Enable PNO */
14280 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014281
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014282 if (( !pnoRequest.ucNetworksCount ) ||
14283 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014284 {
14285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014286 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014287 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014288 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014289 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014290 goto error;
14291 }
14292
14293 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14294 {
14295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014296 "%s: Incorrect number of channels %d",
14297 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014298 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014299 goto error;
14300 }
14301
14302 /* Framework provides one set of channels(all)
14303 * common for all saved profile */
14304 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14305 channels_allowed, &num_channels_allowed))
14306 {
14307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14308 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014309 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014310 goto error;
14311 }
14312 /* Checking each channel against allowed channel list */
14313 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014314 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014315 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014316 char chList [(request->n_channels*5)+1];
14317 int len;
14318 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014319 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014320 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014321 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014322 if (request->channels[i]->hw_value == channels_allowed[indx])
14323 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014324 if ((!pConfig->enableDFSPnoChnlScan) &&
14325 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14326 {
14327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14328 "%s : Dropping DFS channel : %d",
14329 __func__,channels_allowed[indx]);
14330 num_ignore_dfs_ch++;
14331 break;
14332 }
14333
Nirav Shah80830bf2013-12-31 16:35:12 +053014334 valid_ch[num_ch++] = request->channels[i]->hw_value;
14335 len += snprintf(chList+len, 5, "%d ",
14336 request->channels[i]->hw_value);
14337 break ;
14338 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014339 }
14340 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014341 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014342
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014343 /*If all channels are DFS and dropped, then ignore the PNO request*/
14344 if (num_ignore_dfs_ch == request->n_channels)
14345 {
14346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14347 "%s : All requested channels are DFS channels", __func__);
14348 ret = -EINVAL;
14349 goto error;
14350 }
14351 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014352
14353 pnoRequest.aNetworks =
14354 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14355 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014356 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014357 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14358 FL("failed to allocate memory aNetworks %u"),
14359 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14360 goto error;
14361 }
14362 vos_mem_zero(pnoRequest.aNetworks,
14363 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14364
14365 /* Filling per profile params */
14366 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14367 {
14368 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014369 request->match_sets[i].ssid.ssid_len;
14370
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014371 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14372 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014373 {
14374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014375 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014376 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014377 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014378 goto error;
14379 }
14380
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014381 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014382 request->match_sets[i].ssid.ssid,
14383 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14385 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014386 i, pnoRequest.aNetworks[i].ssId.ssId);
14387 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14388 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14389 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014390
14391 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014392 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14393 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014394
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014395 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014396 }
14397
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014398 for (i = 0; i < request->n_ssids; i++)
14399 {
14400 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014401 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014402 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014403 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014404 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014405 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014406 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014407 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014408 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014409 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014410 break;
14411 }
14412 j++;
14413 }
14414 }
14415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14416 "Number of hidden networks being Configured = %d",
14417 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014419 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014420
14421 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14422 if (pnoRequest.p24GProbeTemplate == NULL)
14423 {
14424 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14425 FL("failed to allocate memory p24GProbeTemplate %u"),
14426 SIR_PNO_MAX_PB_REQ_SIZE);
14427 goto error;
14428 }
14429
14430 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14431 if (pnoRequest.p5GProbeTemplate == NULL)
14432 {
14433 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14434 FL("failed to allocate memory p5GProbeTemplate %u"),
14435 SIR_PNO_MAX_PB_REQ_SIZE);
14436 goto error;
14437 }
14438
14439 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14440 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14441
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014442 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14443 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014444 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014445 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14446 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14447 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014448
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014449 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14450 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14451 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014452 }
14453
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014454 /* Driver gets only one time interval which is hardcoded in
14455 * supplicant for 10000ms. Taking power consumption into account 6 timers
14456 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14457 * 80,160,320 secs. And number of scan cycle for each timer
14458 * is configurable through INI param gPNOScanTimerRepeatValue.
14459 * If it is set to 0 only one timer will be used and PNO scan cycle
14460 * will be repeated after each interval specified by supplicant
14461 * till PNO is disabled.
14462 */
14463 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014464 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014465 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014466 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014467 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14468
14469 tempInterval = (request->interval)/1000;
14470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14471 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14472 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014473 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014474 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014475 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014476 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014477 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014478 tempInterval *= 2;
14479 }
14480 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014481 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014482
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014483 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014484
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014485 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014486 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14487 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014488 pAdapter->pno_req_status = 0;
14489
Nirav Shah80830bf2013-12-31 16:35:12 +053014490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14491 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014492 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14493 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014494
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014495 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014496 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014497 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14498 if (eHAL_STATUS_SUCCESS != status)
14499 {
14500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014501 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014502 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014503 goto error;
14504 }
14505
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014506 ret = wait_for_completion_timeout(
14507 &pAdapter->pno_comp_var,
14508 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14509 if (0 >= ret)
14510 {
14511 // Did not receive the response for PNO enable in time.
14512 // Assuming the PNO enable was success.
14513 // Returning error from here, because we timeout, results
14514 // in side effect of Wifi (Wifi Setting) not to work.
14515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14516 FL("Timed out waiting for PNO to be Enabled"));
14517 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014518 }
14519
14520 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014521 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014522
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014523error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14525 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014526 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014527 if (pnoRequest.aNetworks)
14528 vos_mem_free(pnoRequest.aNetworks);
14529 if (pnoRequest.p24GProbeTemplate)
14530 vos_mem_free(pnoRequest.p24GProbeTemplate);
14531 if (pnoRequest.p5GProbeTemplate)
14532 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014533
14534 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014535 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014536}
14537
14538/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014539 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14540 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014541 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014542static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14543 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14544{
14545 int ret;
14546
14547 vos_ssr_protect(__func__);
14548 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14549 vos_ssr_unprotect(__func__);
14550
14551 return ret;
14552}
14553
14554/*
14555 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14556 * Function to disable PNO
14557 */
14558static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014559 struct net_device *dev)
14560{
14561 eHalStatus status = eHAL_STATUS_FAILURE;
14562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14563 hdd_context_t *pHddCtx;
14564 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014565 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014566 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014567
14568 ENTER();
14569
14570 if (NULL == pAdapter)
14571 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014573 "%s: HDD adapter is Null", __func__);
14574 return -ENODEV;
14575 }
14576
14577 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014578
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014579 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014580 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014582 "%s: HDD context is Null", __func__);
14583 return -ENODEV;
14584 }
14585
14586 /* The return 0 is intentional when isLogpInProgress and
14587 * isLoadUnloadInProgress. We did observe a crash due to a return of
14588 * failure in sched_scan_stop , especially for a case where the unload
14589 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14590 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14591 * success. If it returns a failure , then its next invocation due to the
14592 * clean up of the second interface will have the dev pointer corresponding
14593 * to the first one leading to a crash.
14594 */
14595 if (pHddCtx->isLogpInProgress)
14596 {
14597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14598 "%s: LOGP in Progress. Ignore!!!", __func__);
14599 return ret;
14600 }
14601
Mihir Shete18156292014-03-11 15:38:30 +053014602 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014603 {
14604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14605 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14606 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014607 }
14608
14609 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14610 if (NULL == hHal)
14611 {
14612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14613 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014614 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014615 }
14616
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014617 pnoRequest.enable = 0; /* Disable PNO */
14618 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014619
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014620 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014621 pAdapter->sessionId,
14622 NULL, pAdapter);
14623 if (eHAL_STATUS_SUCCESS != status)
14624 {
14625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14626 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014627 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014628 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014629 }
c_hpothu37f21312014-04-09 21:49:54 +053014630 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014631
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014632error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014634 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014635
14636 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014637 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014638}
14639
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014640/*
14641 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14642 * NL interface to disable PNO
14643 */
14644static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14645 struct net_device *dev)
14646{
14647 int ret;
14648
14649 vos_ssr_protect(__func__);
14650 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14651 vos_ssr_unprotect(__func__);
14652
14653 return ret;
14654}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014655#endif /*FEATURE_WLAN_SCAN_PNO*/
14656
14657
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014658#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014659#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014660static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014661 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014662 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14663#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014664static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014665 u8 *peer, u8 action_code, u8 dialog_token,
14666 u16 status_code, const u8 *buf, size_t len)
14667#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014668{
14669
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014670 hdd_adapter_t *pAdapter;
14671 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014672 u8 peerMac[6];
14673 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014674 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014675 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014676 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014677 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014678#if !(TDLS_MGMT_VERSION2)
14679 u32 peer_capability = 0;
14680#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014681 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014682
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014683 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14684 if (NULL == pAdapter)
14685 {
14686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14687 "%s: Adapter is NULL",__func__);
14688 return -EINVAL;
14689 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014690 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14691 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14692 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014693 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014694 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014695 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014697 "Invalid arguments");
14698 return -EINVAL;
14699 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014700 if (pHddCtx->isLogpInProgress)
14701 {
14702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14703 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014704 wlan_hdd_tdls_set_link_status(pAdapter,
14705 peer,
14706 eTDLS_LINK_IDLE,
14707 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014708 return -EBUSY;
14709 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014710 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
14711 {
14712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14713 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14714 return -EAGAIN;
14715 }
Hoonki Lee27511902013-03-14 18:19:06 -070014716 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014717 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014719 "%s: TDLS mode is disabled OR not enabled in FW."
14720 MAC_ADDRESS_STR " action %d declined.",
14721 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014722 return -ENOTSUPP;
14723 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014724
Hoonki Lee27511902013-03-14 18:19:06 -070014725 /* other than teardown frame, other mgmt frames are not sent if disabled */
14726 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14727 {
14728 /* if tdls_mode is disabled to respond to peer's request */
14729 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14730 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070014732 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014733 " TDLS mode is disabled. action %d declined.",
14734 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014735
14736 return -ENOTSUPP;
14737 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014738
14739 if (vos_max_concurrent_connections_reached())
14740 {
14741 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14742 return -EINVAL;
14743 }
Hoonki Lee27511902013-03-14 18:19:06 -070014744 }
14745
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014746 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14747 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053014748 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014749 {
14750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014751 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014752 " TDLS setup is ongoing. action %d declined.",
14753 __func__, MAC_ADDR_ARRAY(peer), action_code);
14754 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014755 }
14756 }
14757
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014758 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14759 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014760 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014761 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14762 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014763 {
14764 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14765 we return error code at 'add_station()'. Hence we have this
14766 check again in addtion to add_station().
14767 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014768 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014769 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14771 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014772 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14773 __func__, MAC_ADDR_ARRAY(peer), action_code,
14774 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014775 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014776 }
14777 else
14778 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014779 /* maximum reached. tweak to send error code to peer and return
14780 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014781 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14783 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014784 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14785 __func__, MAC_ADDR_ARRAY(peer), status_code,
14786 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014787 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014788 /* fall through to send setup resp with failure status
14789 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014790 }
14791 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014792 else
14793 {
14794 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014795 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014796 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014797 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014799 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14800 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014801 return -EPERM;
14802 }
14803 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014804 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014805 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014806
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014808 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014809 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14810 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014811
Hoonki Leea34dd892013-02-05 22:56:02 -080014812 /*Except teardown responder will not be used so just make 0*/
14813 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014814 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014815 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014816
14817 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014818 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014819
14820 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14821 responder = pTdlsPeer->is_responder;
14822 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014823 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014825 "%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 -070014826 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14827 dialog_token, status_code, len);
14828 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014829 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014830 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014831
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014832 /* For explicit trigger of DIS_REQ come out of BMPS for
14833 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014834 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014835 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14836 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014837 {
14838 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14839 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014841 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014842 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14843 if (status != VOS_STATUS_SUCCESS) {
14844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
14845 }
Hoonki Lee14621352013-04-16 17:51:19 -070014846 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014847 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
14848 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED)) {
14849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
14850 }
14851 }
Hoonki Lee14621352013-04-16 17:51:19 -070014852 }
14853
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014854 /* make sure doesn't call send_mgmt() while it is pending */
14855 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14856 {
14857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014858 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014859 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014860 ret = -EBUSY;
14861 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014862 }
14863
14864 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014865 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14866
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014867 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014868 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014869
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014870 if (VOS_STATUS_SUCCESS != status)
14871 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14873 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014874 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014875 ret = -EINVAL;
14876 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014877 }
14878
Hoonki Leed37cbb32013-04-20 00:31:14 -070014879 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14880 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14881
14882 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014883 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014885 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014886 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014887 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014888
14889 if (pHddCtx->isLogpInProgress)
14890 {
14891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14892 "%s: LOGP in Progress. Ignore!!!", __func__);
14893 return -EAGAIN;
14894 }
14895
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014896 ret = -EINVAL;
14897 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014898 }
14899
Gopichand Nakkala05922802013-03-14 12:23:19 -070014900 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014901 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014902 ret = max_sta_failed;
14903 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014904 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014905
Hoonki Leea34dd892013-02-05 22:56:02 -080014906 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14907 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014908 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE)) {
14909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
14910 }
Hoonki Leea34dd892013-02-05 22:56:02 -080014911 }
14912 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14913 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014914 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE)) {
14915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
14916 }
Hoonki Leea34dd892013-02-05 22:56:02 -080014917 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014918
14919 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014920
14921tx_failed:
14922 /* add_station will be called before sending TDLS_SETUP_REQ and
14923 * TDLS_SETUP_RSP and as part of add_station driver will enable
14924 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14925 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14926 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14927 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14928 */
14929
14930 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14931 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14932 wlan_hdd_tdls_check_bmps(pAdapter);
14933 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014934}
14935
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014936#if TDLS_MGMT_VERSION2
14937static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14938 u8 *peer, u8 action_code, u8 dialog_token,
14939 u16 status_code, u32 peer_capability,
14940 const u8 *buf, size_t len)
14941#else
14942static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14943 u8 *peer, u8 action_code, u8 dialog_token,
14944 u16 status_code, const u8 *buf, size_t len)
14945#endif
14946{
14947 int ret;
14948
14949 vos_ssr_protect(__func__);
14950#if TDLS_MGMT_VERSION2
14951 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14952 status_code, peer_capability, buf, len);
14953#else
14954 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14955 status_code, buf, len);
14956#endif
14957 vos_ssr_unprotect(__func__);
14958
14959 return ret;
14960}
Atul Mittal115287b2014-07-08 13:26:33 +053014961
14962int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14963 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014964 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014965 cfg80211_exttdls_callback callback)
14966{
14967
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014968 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014969 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053014970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053014971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14972 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14973 __func__, MAC_ADDR_ARRAY(peer));
14974
14975 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14976 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14977
14978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014979 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
14980 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
14981 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053014982 return -ENOTSUPP;
14983 }
14984
14985 /* To cater the requirement of establishing the TDLS link
14986 * irrespective of the data traffic , get an entry of TDLS peer.
14987 */
14988 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14989 if (pTdlsPeer == NULL) {
14990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14991 "%s: peer " MAC_ADDRESS_STR " not existing",
14992 __func__, MAC_ADDR_ARRAY(peer));
14993 return -EINVAL;
14994 }
14995
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053014996 /* check FW TDLS Off Channel capability */
14997 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
14998 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014999 {
15000 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15001 pTdlsPeer->peerParams.global_operating_class =
15002 tdls_peer_params->global_operating_class;
15003 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15004 pTdlsPeer->peerParams.min_bandwidth_kbps =
15005 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015006 /* check configured channel is valid, non dfs and
15007 * not current operating channel */
15008 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15009 tdls_peer_params->channel)) &&
15010 (pHddStaCtx) &&
15011 (tdls_peer_params->channel !=
15012 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015013 {
15014 pTdlsPeer->isOffChannelConfigured = TRUE;
15015 }
15016 else
15017 {
15018 pTdlsPeer->isOffChannelConfigured = FALSE;
15019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15020 "%s: Configured Tdls Off Channel is not valid", __func__);
15021
15022 }
15023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015024 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15025 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015026 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015027 pTdlsPeer->isOffChannelConfigured,
15028 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015029 }
15030 else
15031 {
15032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015033 "%s: TDLS off channel FW capability %d or "
15034 "Invalid TDLS Peer Params", __func__,
15035 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015036 }
15037
Atul Mittal115287b2014-07-08 13:26:33 +053015038 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15039
15040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15041 " %s TDLS Add Force Peer Failed",
15042 __func__);
15043 return -EINVAL;
15044 }
15045 /*EXT TDLS*/
15046
15047 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15049 " %s TDLS set callback Failed",
15050 __func__);
15051 return -EINVAL;
15052 }
15053
15054 return(0);
15055
15056}
15057
15058int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
15059{
15060
15061 hddTdlsPeer_t *pTdlsPeer;
15062 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15064 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15065 __func__, MAC_ADDR_ARRAY(peer));
15066
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015067 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15069 return -EINVAL;
15070 }
15071
Atul Mittal115287b2014-07-08 13:26:33 +053015072 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15073 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15074
15075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015076 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15077 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15078 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015079 return -ENOTSUPP;
15080 }
15081
15082
15083 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15084
15085 if ( NULL == pTdlsPeer ) {
15086 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
15087 " peer not exsting",
15088 __func__, MAC_ADDR_ARRAY(peer));
15089 return -EINVAL;
15090 }
15091 else {
15092 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15093 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015094 /* if channel switch is configured, reset
15095 the channel for this peer */
15096 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15097 {
15098 pTdlsPeer->peerParams.channel = 0;
15099 pTdlsPeer->isOffChannelConfigured = FALSE;
15100 }
Atul Mittal115287b2014-07-08 13:26:33 +053015101 }
15102
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015103 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015105 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015106 }
Atul Mittal115287b2014-07-08 13:26:33 +053015107
15108 /*EXT TDLS*/
15109
15110 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15111
15112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15113 " %s TDLS set callback Failed",
15114 __func__);
15115 return -EINVAL;
15116 }
15117 return(0);
15118
15119}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015120static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015121 u8 *peer, enum nl80211_tdls_operation oper)
15122{
15123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15124 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015125 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015126 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015127
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015128 ENTER();
15129
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015130 if (!pAdapter) {
15131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15132 return -EINVAL;
15133 }
15134
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015135 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15136 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15137 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015138 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015139 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015141 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015142 return -EINVAL;
15143 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015144
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015145 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015146 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015147 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015148 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015149 }
15150
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015151
15152 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015153 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015154 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015156 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15157 "Cannot process TDLS commands",
15158 pHddCtx->cfg_ini->fEnableTDLSSupport,
15159 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015160 return -ENOTSUPP;
15161 }
15162
15163 switch (oper) {
15164 case NL80211_TDLS_ENABLE_LINK:
15165 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015166 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015167 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015168 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015169 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015170 tANI_U16 numCurrTdlsPeers = 0;
15171 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015172
Sunil Dutt41de4e22013-11-14 18:09:02 +053015173 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015174 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015175 if ( NULL == pTdlsPeer ) {
15176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15177 " (oper %d) not exsting. ignored",
15178 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15179 return -EINVAL;
15180 }
15181
15182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15183 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15184 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15185 "NL80211_TDLS_ENABLE_LINK");
15186
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015187 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15188 {
15189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15190 MAC_ADDRESS_STR " failed",
15191 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15192 return -EINVAL;
15193 }
15194
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015195 /* TDLS Off Channel, Disable tdls channel switch,
15196 when there are more than one tdls link */
15197 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015198 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015199 {
15200 /* get connected peer and send disable tdls off chan */
15201 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15202 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
15203 {
15204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15205 "%s: More then one peer connected, Disable "
15206 "TDLS channel switch", __func__);
15207
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015208 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015209 ret = sme_SendTdlsChanSwitchReq(
15210 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015211 pAdapter->sessionId,
15212 connPeer->peerMac,
15213 connPeer->peerParams.channel,
15214 TDLS_OFF_CHANNEL_BW_OFFSET,
15215 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015216 if (ret != VOS_STATUS_SUCCESS) {
15217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel request"));
15218 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015219 }
15220 else
15221 {
15222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15223 "%s: No TDLS Connected Peer or "
15224 "isOffChannelConfigured %d",
15225 __func__,
15226 (connPeer ? connPeer->isOffChannelConfigured : -1));
15227 }
15228 }
15229
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015230 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015231 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015232 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015233
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015234 if (0 != wlan_hdd_tdls_get_link_establish_params(
15235 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015237 return -EINVAL;
15238 }
15239 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015240
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015241 ret = sme_SendTdlsLinkEstablishParams(
15242 WLAN_HDD_GET_HAL_CTX(pAdapter),
15243 pAdapter->sessionId, peer,
15244 &tdlsLinkEstablishParams);
15245 if (ret != VOS_STATUS_SUCCESS) {
15246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15247 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015248 /* Send TDLS peer UAPSD capabilities to the firmware and
15249 * register with the TL on after the response for this operation
15250 * is received .
15251 */
15252 ret = wait_for_completion_interruptible_timeout(
15253 &pAdapter->tdls_link_establish_req_comp,
15254 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15255 if (ret <= 0)
15256 {
15257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15258 "%s: Link Establish Request Faled Status %ld",
15259 __func__, ret);
15260 return -EINVAL;
15261 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015262 }
Atul Mittal115287b2014-07-08 13:26:33 +053015263 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15264 eTDLS_LINK_CONNECTED,
15265 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015266 staDesc.ucSTAId = pTdlsPeer->staId;
15267 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015268 ret = WLANTL_UpdateTdlsSTAClient(
15269 pHddCtx->pvosContext,
15270 &staDesc);
15271 if (ret != VOS_STATUS_SUCCESS) {
15272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15273 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015274
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015275 /* Mark TDLS client Authenticated .*/
15276 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15277 pTdlsPeer->staId,
15278 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015279 if (VOS_STATUS_SUCCESS == status)
15280 {
Hoonki Lee14621352013-04-16 17:51:19 -070015281 if (pTdlsPeer->is_responder == 0)
15282 {
15283 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15284
15285 wlan_hdd_tdls_timer_restart(pAdapter,
15286 &pTdlsPeer->initiatorWaitTimeoutTimer,
15287 WAIT_TIME_TDLS_INITIATOR);
15288 /* suspend initiator TX until it receives direct packet from the
15289 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015290 ret = WLANTL_SuspendDataTx(
15291 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15292 &staId, NULL);
15293 if (ret != VOS_STATUS_SUCCESS) {
15294 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15295 }
Hoonki Lee14621352013-04-16 17:51:19 -070015296 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015297
15298 /* TDLS Off Channel, Enable tdls channel switch,
15299 when their is only one tdls link and it supports */
15300 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15301 if ((numCurrTdlsPeers == 1) &&
15302 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15303 (TRUE == pTdlsPeer->isOffChannelConfigured))
15304 {
15305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15306 "%s: Send TDLS channel switch request for channel %d",
15307 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015308
15309 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015310 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15311 pAdapter->sessionId,
15312 pTdlsPeer->peerMac,
15313 pTdlsPeer->peerParams.channel,
15314 TDLS_OFF_CHANNEL_BW_OFFSET,
15315 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015316 if (ret != VOS_STATUS_SUCCESS) {
15317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15318 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015319 }
15320 else
15321 {
15322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15323 "%s: TDLS channel switch request not sent"
15324 " numCurrTdlsPeers %d "
15325 "isOffChannelSupported %d "
15326 "isOffChannelConfigured %d",
15327 __func__, numCurrTdlsPeers,
15328 pTdlsPeer->isOffChannelSupported,
15329 pTdlsPeer->isOffChannelConfigured);
15330 }
15331
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015332 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015333 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015334
15335 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015336 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15337 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015338 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015339 int ac;
15340 uint8 ucAc[4] = { WLANTL_AC_VO,
15341 WLANTL_AC_VI,
15342 WLANTL_AC_BK,
15343 WLANTL_AC_BE };
15344 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15345 for(ac=0; ac < 4; ac++)
15346 {
15347 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15348 pTdlsPeer->staId, ucAc[ac],
15349 tlTid[ac], tlTid[ac], 0, 0,
15350 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015351 if (status != VOS_STATUS_SUCCESS) {
15352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15353 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015354 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015355 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015356 }
15357
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015358 }
15359 break;
15360 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015361 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015362 tANI_U16 numCurrTdlsPeers = 0;
15363 hddTdlsPeer_t *connPeer = NULL;
15364
Sunil Dutt41de4e22013-11-14 18:09:02 +053015365 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15366
15367 if ( NULL == pTdlsPeer ) {
15368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15369 " (oper %d) not exsting. ignored",
15370 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15371 return -EINVAL;
15372 }
15373
15374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15375 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15376 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15377 "NL80211_TDLS_DISABLE_LINK");
15378
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015379 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015380 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015381 long status;
15382
Atul Mittal271a7652014-09-12 13:18:22 +053015383
15384 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15385 eTDLS_LINK_TEARING,
15386 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15387 eTDLS_LINK_UNSPECIFIED:
15388 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015389 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15390
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015391 status = sme_DeleteTdlsPeerSta(
15392 WLAN_HDD_GET_HAL_CTX(pAdapter),
15393 pAdapter->sessionId, peer );
15394 if (status != VOS_STATUS_SUCCESS) {
15395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15396 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015397
15398 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15399 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015400 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015401 eTDLS_LINK_IDLE,
15402 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015403 if (status <= 0)
15404 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15406 "%s: Del station failed status %ld",
15407 __func__, status);
15408 return -EPERM;
15409 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015410
15411 /* TDLS Off Channel, Enable tdls channel switch,
15412 when their is only one tdls link and it supports */
15413 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15414 if (numCurrTdlsPeers == 1)
15415 {
15416 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15417 if ((connPeer) &&
15418 (connPeer->isOffChannelSupported == TRUE) &&
15419 (connPeer->isOffChannelConfigured == TRUE))
15420 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015421 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015422 status = sme_SendTdlsChanSwitchReq(
15423 WLAN_HDD_GET_HAL_CTX(pAdapter),
15424 pAdapter->sessionId,
15425 connPeer->peerMac,
15426 connPeer->peerParams.channel,
15427 TDLS_OFF_CHANNEL_BW_OFFSET,
15428 TDLS_CHANNEL_SWITCH_ENABLE);
15429 if (status != VOS_STATUS_SUCCESS) {
15430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15431 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015432 }
15433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15434 "%s: TDLS channel switch "
15435 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015436 "isOffChannelConfigured %d "
15437 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015438 __func__,
15439 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015440 (connPeer ? connPeer->isOffChannelConfigured : -1),
15441 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015442 }
15443 else
15444 {
15445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15446 "%s: TDLS channel switch request not sent "
15447 "numCurrTdlsPeers %d ",
15448 __func__, numCurrTdlsPeers);
15449 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015450 }
15451 else
15452 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15454 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015455 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015456 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015457 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015458 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015459 {
Atul Mittal115287b2014-07-08 13:26:33 +053015460 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015461
Atul Mittal115287b2014-07-08 13:26:33 +053015462 if (0 != status)
15463 {
15464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15465 "%s: Error in TDLS Teardown", __func__);
15466 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015467 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015468 break;
15469 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015470 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015471 {
Atul Mittal115287b2014-07-08 13:26:33 +053015472 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15473 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015474 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015475 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015476
Atul Mittal115287b2014-07-08 13:26:33 +053015477 if (0 != status)
15478 {
15479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15480 "%s: Error in TDLS Setup", __func__);
15481 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015482 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015483 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015484 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015485 case NL80211_TDLS_DISCOVERY_REQ:
15486 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15488 "%s: We don't support in-driver setup/teardown/discovery "
15489 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015490 return -ENOTSUPP;
15491 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15493 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015494 return -ENOTSUPP;
15495 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015496
15497 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015498 return 0;
15499}
Chilam NG571c65a2013-01-19 12:27:36 +053015500
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015501static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
15502 u8 *peer, enum nl80211_tdls_operation oper)
15503{
15504 int ret;
15505
15506 vos_ssr_protect(__func__);
15507 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15508 vos_ssr_unprotect(__func__);
15509
15510 return ret;
15511}
15512
Chilam NG571c65a2013-01-19 12:27:36 +053015513int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15514 struct net_device *dev, u8 *peer)
15515{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015516 hddLog(VOS_TRACE_LEVEL_INFO,
15517 "tdls send discover req: "MAC_ADDRESS_STR,
15518 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015519
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015520#if TDLS_MGMT_VERSION2
15521 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15522 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15523#else
Chilam NG571c65a2013-01-19 12:27:36 +053015524 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15525 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015526#endif
Chilam NG571c65a2013-01-19 12:27:36 +053015527}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015528#endif
15529
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015530#ifdef WLAN_FEATURE_GTK_OFFLOAD
15531/*
15532 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15533 * Callback rountine called upon receiving response for
15534 * get offload info
15535 */
15536void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15537 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15538{
15539
15540 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015541 tANI_U8 tempReplayCounter[8];
15542 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015543
15544 ENTER();
15545
15546 if (NULL == pAdapter)
15547 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015549 "%s: HDD adapter is Null", __func__);
15550 return ;
15551 }
15552
15553 if (NULL == pGtkOffloadGetInfoRsp)
15554 {
15555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15556 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
15557 return ;
15558 }
15559
15560 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
15561 {
15562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15563 "%s: wlan Failed to get replay counter value",
15564 __func__);
15565 return ;
15566 }
15567
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015568 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15569 /* Update replay counter */
15570 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
15571 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15572
15573 {
15574 /* changing from little to big endian since supplicant
15575 * works on big endian format
15576 */
15577 int i;
15578 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
15579
15580 for (i = 0; i < 8; i++)
15581 {
15582 tempReplayCounter[7-i] = (tANI_U8)p[i];
15583 }
15584 }
15585
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015586 /* Update replay counter to NL */
15587 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015588 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015589}
15590
15591/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015592 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015593 * This function is used to offload GTK rekeying job to the firmware.
15594 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015595int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015596 struct cfg80211_gtk_rekey_data *data)
15597{
15598 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15599 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15600 hdd_station_ctx_t *pHddStaCtx;
15601 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015602 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015603 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015604 eHalStatus status = eHAL_STATUS_FAILURE;
15605
15606 ENTER();
15607
15608 if (NULL == pAdapter)
15609 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015611 "%s: HDD adapter is Null", __func__);
15612 return -ENODEV;
15613 }
15614
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015615 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15616 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
15617 pAdapter->sessionId, pAdapter->device_mode));
15618
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015619 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015620 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015621 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015622 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015623 }
15624
15625 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15626 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15627 if (NULL == hHal)
15628 {
15629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15630 "%s: HAL context is Null!!!", __func__);
15631 return -EAGAIN;
15632 }
15633
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015634 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
15635 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
15636 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
15637 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015638 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015639 {
15640 /* changing from big to little endian since driver
15641 * works on little endian format
15642 */
15643 tANI_U8 *p =
15644 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
15645 int i;
15646
15647 for (i = 0; i < 8; i++)
15648 {
15649 p[7-i] = data->replay_ctr[i];
15650 }
15651 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015652
15653 if (TRUE == pHddCtx->hdd_wlan_suspended)
15654 {
15655 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015656 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
15657 sizeof (tSirGtkOffloadParams));
15658 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015659 pAdapter->sessionId);
15660
15661 if (eHAL_STATUS_SUCCESS != status)
15662 {
15663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15664 "%s: sme_SetGTKOffload failed, returned %d",
15665 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015666
15667 /* Need to clear any trace of key value in the memory.
15668 * Thus zero out the memory even though it is local
15669 * variable.
15670 */
15671 vos_mem_zero(&hddGtkOffloadReqParams,
15672 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015673 return status;
15674 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15676 "%s: sme_SetGTKOffload successfull", __func__);
15677 }
15678 else
15679 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15681 "%s: wlan not suspended GTKOffload request is stored",
15682 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015683 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015684
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053015685 /* Need to clear any trace of key value in the memory.
15686 * Thus zero out the memory even though it is local
15687 * variable.
15688 */
15689 vos_mem_zero(&hddGtkOffloadReqParams,
15690 sizeof(hddGtkOffloadReqParams));
15691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015692 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015693 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015694}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015695
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015696int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
15697 struct cfg80211_gtk_rekey_data *data)
15698{
15699 int ret;
15700
15701 vos_ssr_protect(__func__);
15702 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
15703 vos_ssr_unprotect(__func__);
15704
15705 return ret;
15706}
15707#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015708/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015709 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015710 * This function is used to set access control policy
15711 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015712static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15713 struct net_device *dev,
15714 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015715{
15716 int i;
15717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15718 hdd_hostapd_state_t *pHostapdState;
15719 tsap_Config_t *pConfig;
15720 v_CONTEXT_t pVosContext = NULL;
15721 hdd_context_t *pHddCtx;
15722 int status;
15723
15724 ENTER();
15725
15726 if (NULL == pAdapter)
15727 {
15728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15729 "%s: HDD adapter is Null", __func__);
15730 return -ENODEV;
15731 }
15732
15733 if (NULL == params)
15734 {
15735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15736 "%s: params is Null", __func__);
15737 return -EINVAL;
15738 }
15739
15740 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15741 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015742 if (0 != status)
15743 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015744 return status;
15745 }
15746
15747 pVosContext = pHddCtx->pvosContext;
15748 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15749
15750 if (NULL == pHostapdState)
15751 {
15752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15753 "%s: pHostapdState is Null", __func__);
15754 return -EINVAL;
15755 }
15756
15757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15758 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15759
15760 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15761 {
15762 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15763
15764 /* default value */
15765 pConfig->num_accept_mac = 0;
15766 pConfig->num_deny_mac = 0;
15767
15768 /**
15769 * access control policy
15770 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15771 * listed in hostapd.deny file.
15772 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15773 * listed in hostapd.accept file.
15774 */
15775 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15776 {
15777 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15778 }
15779 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15780 {
15781 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15782 }
15783 else
15784 {
15785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15786 "%s:Acl Policy : %d is not supported",
15787 __func__, params->acl_policy);
15788 return -ENOTSUPP;
15789 }
15790
15791 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15792 {
15793 pConfig->num_accept_mac = params->n_acl_entries;
15794 for (i = 0; i < params->n_acl_entries; i++)
15795 {
15796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15797 "** Add ACL MAC entry %i in WhiletList :"
15798 MAC_ADDRESS_STR, i,
15799 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15800
15801 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15802 sizeof(qcmacaddr));
15803 }
15804 }
15805 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15806 {
15807 pConfig->num_deny_mac = params->n_acl_entries;
15808 for (i = 0; i < params->n_acl_entries; i++)
15809 {
15810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15811 "** Add ACL MAC entry %i in BlackList :"
15812 MAC_ADDRESS_STR, i,
15813 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15814
15815 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15816 sizeof(qcmacaddr));
15817 }
15818 }
15819
15820 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15821 {
15822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15823 "%s: SAP Set Mac Acl fail", __func__);
15824 return -EINVAL;
15825 }
15826 }
15827 else
15828 {
15829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015830 "%s: Invalid device_mode = %s (%d)",
15831 __func__, hdd_device_modetoString(pAdapter->device_mode),
15832 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015833 return -EINVAL;
15834 }
15835
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015836 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015837 return 0;
15838}
15839
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015840static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15841 struct net_device *dev,
15842 const struct cfg80211_acl_data *params)
15843{
15844 int ret;
15845 vos_ssr_protect(__func__);
15846 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15847 vos_ssr_unprotect(__func__);
15848
15849 return ret;
15850}
15851
Leo Chang9056f462013-08-01 19:21:11 -070015852#ifdef WLAN_NL80211_TESTMODE
15853#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015854void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015855(
15856 void *pAdapter,
15857 void *indCont
15858)
15859{
Leo Changd9df8aa2013-09-26 13:32:26 -070015860 tSirLPHBInd *lphbInd;
15861 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015862 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015863
15864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015865 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015866
c_hpothu73f35e62014-04-18 13:40:08 +053015867 if (pAdapter == NULL)
15868 {
15869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15870 "%s: pAdapter is NULL\n",__func__);
15871 return;
15872 }
15873
Leo Chang9056f462013-08-01 19:21:11 -070015874 if (NULL == indCont)
15875 {
15876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015877 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015878 return;
15879 }
15880
c_hpothu73f35e62014-04-18 13:40:08 +053015881 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015882 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015883 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015884 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015885 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015886 GFP_ATOMIC);
15887 if (!skb)
15888 {
15889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15890 "LPHB timeout, NL buffer alloc fail");
15891 return;
15892 }
15893
Leo Changac3ba772013-10-07 09:47:04 -070015894 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015895 {
15896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15897 "WLAN_HDD_TM_ATTR_CMD put fail");
15898 goto nla_put_failure;
15899 }
Leo Changac3ba772013-10-07 09:47:04 -070015900 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015901 {
15902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15903 "WLAN_HDD_TM_ATTR_TYPE put fail");
15904 goto nla_put_failure;
15905 }
Leo Changac3ba772013-10-07 09:47:04 -070015906 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015907 sizeof(tSirLPHBInd), lphbInd))
15908 {
15909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15910 "WLAN_HDD_TM_ATTR_DATA put fail");
15911 goto nla_put_failure;
15912 }
Leo Chang9056f462013-08-01 19:21:11 -070015913 cfg80211_testmode_event(skb, GFP_ATOMIC);
15914 return;
15915
15916nla_put_failure:
15917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15918 "NLA Put fail");
15919 kfree_skb(skb);
15920
15921 return;
15922}
15923#endif /* FEATURE_WLAN_LPHB */
15924
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015925static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015926{
15927 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15928 int err = 0;
15929#ifdef FEATURE_WLAN_LPHB
15930 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015931 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015932
15933 ENTER();
15934
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015935 err = wlan_hdd_validate_context(pHddCtx);
15936 if (0 != err)
15937 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015938 return err;
15939 }
Leo Chang9056f462013-08-01 19:21:11 -070015940#endif /* FEATURE_WLAN_LPHB */
15941
15942 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15943 if (err)
15944 {
15945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15946 "%s Testmode INV ATTR", __func__);
15947 return err;
15948 }
15949
15950 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15951 {
15952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15953 "%s Testmode INV CMD", __func__);
15954 return -EINVAL;
15955 }
15956
15957 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15958 {
15959#ifdef FEATURE_WLAN_LPHB
15960 /* Low Power Heartbeat configuration request */
15961 case WLAN_HDD_TM_CMD_WLAN_HB:
15962 {
15963 int buf_len;
15964 void *buf;
15965 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015966 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015967
15968 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15969 {
15970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15971 "%s Testmode INV DATA", __func__);
15972 return -EINVAL;
15973 }
15974
15975 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15976 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015977
15978 hb_params_temp =(tSirLPHBReq *)buf;
15979 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15980 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15981 return -EINVAL;
15982
Leo Chang9056f462013-08-01 19:21:11 -070015983 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15984 if (NULL == hb_params)
15985 {
15986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15987 "%s Request Buffer Alloc Fail", __func__);
15988 return -EINVAL;
15989 }
15990
15991 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015992 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15993 hb_params,
15994 wlan_hdd_cfg80211_lphb_ind_handler);
15995 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015996 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15998 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015999 vos_mem_free(hb_params);
16000 }
Leo Chang9056f462013-08-01 19:21:11 -070016001 return 0;
16002 }
16003#endif /* FEATURE_WLAN_LPHB */
16004 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16006 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016007 return -EOPNOTSUPP;
16008 }
16009
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016010 EXIT();
16011 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016012}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016013
16014static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
16015{
16016 int ret;
16017
16018 vos_ssr_protect(__func__);
16019 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16020 vos_ssr_unprotect(__func__);
16021
16022 return ret;
16023}
Leo Chang9056f462013-08-01 19:21:11 -070016024#endif /* CONFIG_NL80211_TESTMODE */
16025
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016026static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016027 struct net_device *dev,
16028 int idx, struct survey_info *survey)
16029{
16030 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16031 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016032 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016033 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016034 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016035 v_S7_t snr,rssi;
16036 int status, i, j, filled = 0;
16037
16038 ENTER();
16039
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016040 if (NULL == pAdapter)
16041 {
16042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16043 "%s: HDD adapter is Null", __func__);
16044 return -ENODEV;
16045 }
16046
16047 if (NULL == wiphy)
16048 {
16049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16050 "%s: wiphy is Null", __func__);
16051 return -ENODEV;
16052 }
16053
16054 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16055 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016056 if (0 != status)
16057 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016058 return status;
16059 }
16060
Mihir Sheted9072e02013-08-21 17:02:29 +053016061 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16062
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016063 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016064 0 != pAdapter->survey_idx ||
16065 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016066 {
16067 /* The survey dump ops when implemented completely is expected to
16068 * return a survey of all channels and the ops is called by the
16069 * kernel with incremental values of the argument 'idx' till it
16070 * returns -ENONET. But we can only support the survey for the
16071 * operating channel for now. survey_idx is used to track
16072 * that the ops is called only once and then return -ENONET for
16073 * the next iteration
16074 */
16075 pAdapter->survey_idx = 0;
16076 return -ENONET;
16077 }
16078
16079 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16080
16081 wlan_hdd_get_snr(pAdapter, &snr);
16082 wlan_hdd_get_rssi(pAdapter, &rssi);
16083
16084 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16085 hdd_wlan_get_freq(channel, &freq);
16086
16087
16088 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16089 {
16090 if (NULL == wiphy->bands[i])
16091 {
16092 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16093 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16094 continue;
16095 }
16096
16097 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16098 {
16099 struct ieee80211_supported_band *band = wiphy->bands[i];
16100
16101 if (band->channels[j].center_freq == (v_U16_t)freq)
16102 {
16103 survey->channel = &band->channels[j];
16104 /* The Rx BDs contain SNR values in dB for the received frames
16105 * while the supplicant expects noise. So we calculate and
16106 * return the value of noise (dBm)
16107 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16108 */
16109 survey->noise = rssi - snr;
16110 survey->filled = SURVEY_INFO_NOISE_DBM;
16111 filled = 1;
16112 }
16113 }
16114 }
16115
16116 if (filled)
16117 pAdapter->survey_idx = 1;
16118 else
16119 {
16120 pAdapter->survey_idx = 0;
16121 return -ENONET;
16122 }
16123
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016124 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016125 return 0;
16126}
16127
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016128static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16129 struct net_device *dev,
16130 int idx, struct survey_info *survey)
16131{
16132 int ret;
16133
16134 vos_ssr_protect(__func__);
16135 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16136 vos_ssr_unprotect(__func__);
16137
16138 return ret;
16139}
16140
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016141/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016142 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016143 * this is called when cfg80211 driver resume
16144 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16145 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016146int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016147{
16148 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16149 hdd_adapter_t *pAdapter;
16150 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16151 VOS_STATUS status = VOS_STATUS_SUCCESS;
16152
16153 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016154
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016155 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016156 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016157 return 0;
16158 }
16159
16160 spin_lock(&pHddCtx->schedScan_lock);
16161 pHddCtx->isWiphySuspended = FALSE;
16162 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16163 {
16164 spin_unlock(&pHddCtx->schedScan_lock);
16165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16166 "%s: Return resume is not due to PNO indication", __func__);
16167 return 0;
16168 }
16169 // Reset flag to avoid updatating cfg80211 data old results again
16170 pHddCtx->isSchedScanUpdatePending = FALSE;
16171 spin_unlock(&pHddCtx->schedScan_lock);
16172
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016173
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016174 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16175
16176 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16177 {
16178 pAdapter = pAdapterNode->pAdapter;
16179 if ( (NULL != pAdapter) &&
16180 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16181 {
16182 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016183 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16185 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016186 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016187 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016188 {
16189 /* Acquire wakelock to handle the case where APP's tries to
16190 * suspend immediately after updating the scan results. Whis
16191 * results in app's is in suspended state and not able to
16192 * process the connect request to AP
16193 */
16194 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016195 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016196 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016197
16198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16199 "%s : cfg80211 scan result database updated", __func__);
16200
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016201 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016202 return 0;
16203
16204 }
16205 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16206 pAdapterNode = pNext;
16207 }
16208
16209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16210 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016211 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016212 return 0;
16213}
16214
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016215int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16216{
16217 int ret;
16218
16219 vos_ssr_protect(__func__);
16220 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16221 vos_ssr_unprotect(__func__);
16222
16223 return ret;
16224}
16225
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016226/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016227 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016228 * this is called when cfg80211 driver suspends
16229 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016230int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016231 struct cfg80211_wowlan *wow)
16232{
16233 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016234 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016235
16236 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016237
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016238 ret = wlan_hdd_validate_context(pHddCtx);
16239 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016240 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016241 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016242 }
16243
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016244
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016245 pHddCtx->isWiphySuspended = TRUE;
16246
16247 EXIT();
16248
16249 return 0;
16250}
16251
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016252int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16253 struct cfg80211_wowlan *wow)
16254{
16255 int ret;
16256
16257 vos_ssr_protect(__func__);
16258 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16259 vos_ssr_unprotect(__func__);
16260
16261 return ret;
16262}
Jeff Johnson295189b2012-06-20 16:38:30 -070016263/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016264static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016265{
16266 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16267 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16268 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16269 .change_station = wlan_hdd_change_station,
16270#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16271 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16272 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16273 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016274#else
16275 .start_ap = wlan_hdd_cfg80211_start_ap,
16276 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16277 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016278#endif
16279 .change_bss = wlan_hdd_cfg80211_change_bss,
16280 .add_key = wlan_hdd_cfg80211_add_key,
16281 .get_key = wlan_hdd_cfg80211_get_key,
16282 .del_key = wlan_hdd_cfg80211_del_key,
16283 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016284#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016285 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016287 .scan = wlan_hdd_cfg80211_scan,
16288 .connect = wlan_hdd_cfg80211_connect,
16289 .disconnect = wlan_hdd_cfg80211_disconnect,
16290 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16291 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16292 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16293 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16294 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016295 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16296 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016297 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016298#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16299 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16300 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16301 .set_txq_params = wlan_hdd_set_txq_params,
16302#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016303 .get_station = wlan_hdd_cfg80211_get_station,
16304 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16305 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016306 .add_station = wlan_hdd_cfg80211_add_station,
16307#ifdef FEATURE_WLAN_LFR
16308 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16309 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16310 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16311#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016312#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16313 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16314#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016315#ifdef FEATURE_WLAN_TDLS
16316 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16317 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16318#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016319#ifdef WLAN_FEATURE_GTK_OFFLOAD
16320 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16321#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016322#ifdef FEATURE_WLAN_SCAN_PNO
16323 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16324 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16325#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016326 .resume = wlan_hdd_cfg80211_resume_wlan,
16327 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016328 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016329#ifdef WLAN_NL80211_TESTMODE
16330 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16331#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016332 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016333};
16334