blob: 1c2c8f53ebec48e360fc5aae3e4eac38a86687d2 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -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/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_assoc.c
30 *
31 * WLAN Host Device Driver implementation
32 *
33 */
34
35#include "wlan_hdd_includes.h"
36#include <ani_global.h>
37#include "dot11f.h"
38#include "wlan_hdd_power.h"
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +053039#include "wlan_hdd_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080040#include <linux/ieee80211.h>
41#include <linux/wireless.h>
42#include <linux/etherdevice.h>
43#include <net/cfg80211.h>
44#include "wlan_hdd_cfg80211.h"
45#include "csr_inside_api.h"
46#include "wlan_hdd_p2p.h"
47#ifdef FEATURE_WLAN_TDLS
48#include "wlan_hdd_tdls.h"
49#endif
50#include "sme_api.h"
51#include "wlan_hdd_hostapd.h"
52#include <wlan_hdd_ipa.h>
53#include <cds_sched.h>
54#include "cds_concurrency.h"
55#include "sme_power_save_api.h"
56#include "ol_txrx_ctrl_api.h"
57#include "ol_txrx_types.h"
Dhanashri Atre182b0272016-02-17 15:35:07 -080058#include "ol_txrx.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080059#include "cdp_txrx_flow_ctrl_legacy.h"
60#include "cdp_txrx_peer_ops.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061
62/* These are needed to recognize WPA and RSN suite types */
63#define HDD_WPA_OUI_SIZE 4
64#define HDD_RSN_OUI_SIZE 4
65uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
66uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
67uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
68uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
69uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
70uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
71
72#ifdef FEATURE_WLAN_ESE
73/* CCKM */
74uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
75/* CCKM */
76uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
77#endif /* FEATURE_WLAN_ESE */
78
79/* group cipher */
80uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
81
82/* WEP-40 or RSN */
83uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
84
85/* TKIP or RSN-PSK */
86uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
87
88/* Reserved */
89uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
90
91/* AES-CCMP */
92uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
93
94/* WEP-104 */
95uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
96
97#ifdef WLAN_FEATURE_11W
98/* RSN-PSK-SHA256 */
99uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
100
101/* RSN-8021X-SHA256 */
102uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
103#endif
104
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800105/* Offset where the EID-Len-IE, start. */
106#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
107#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800108
109#define BEACON_FRAME_IES_OFFSET 12
110#define HDD_PEER_AUTHORIZE_WAIT 10
111
112/**
113 * hdd_conn_set_authenticated() - set authentication state
114 * @pAdapter: pointer to the adapter
115 * @authState: authentication state
116 *
117 * This function updates the global HDD station context
118 * authentication state.
119 *
120 * Return: none
121 */
122static void
123hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
124{
125 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
126 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
127
128 /* save the new connection state */
129 hddLog(LOG1,
130 FL("Authenticated state Changed from oldState:%d to State:%d"),
131 pHddStaCtx->conn_info.uIsAuthenticated, authState);
132 pHddStaCtx->conn_info.uIsAuthenticated = authState;
133
134 /* Check is pending ROC request or not when auth state changed */
135 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
136}
137
138/**
139 * hdd_conn_set_connection_state() - set connection state
140 * @pAdapter: pointer to the adapter
141 * @connState: connection state
142 *
143 * This function updates the global HDD station context connection state.
144 *
145 * Return: none
146 */
147void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
148 eConnectionState connState)
149{
150 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
151 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
152
153 /* save the new connection state */
154 hddLog(LOG1, FL("ConnectionState Changed from oldState:%d to State:%d"),
155 pHddStaCtx->conn_info.connState, connState);
156 pHddStaCtx->conn_info.connState = connState;
157
158 /* Check is pending ROC request or not when connection state changed */
159 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
160}
161
162/**
163 * hdd_conn_get_connection_state() - get connection state
164 * @pAdapter: pointer to the adapter
165 * @pConnState: pointer to connection state
166 *
167 * This function updates the global HDD station context connection state.
168 *
169 * Return: true if (Infra Associated or IBSS Connected)
170 * and sets output parameter pConnState;
171 * false otherwise
172 */
173static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
174 eConnectionState *pConnState)
175{
176 bool fConnected = false;
177 eConnectionState connState;
178
179 /* get the connection state. */
180 connState = pHddStaCtx->conn_info.connState;
181
182 if (eConnectionState_Associated == connState ||
183 eConnectionState_IbssConnected == connState ||
184 eConnectionState_IbssDisconnected == connState) {
185 fConnected = true;
186 }
187
188 if (pConnState)
189 *pConnState = connState;
190
191 return fConnected;
192}
193
194/**
195 * hdd_is_connecting() - Function to check connection progress
196 * @hdd_sta_ctx: pointer to global HDD Station context
197 *
198 * Return: true if connecting, false otherwise
199 */
200bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
201{
202 return hdd_sta_ctx->conn_info.connState ==
203 eConnectionState_Connecting;
204}
205
206/**
207 * hdd_conn_is_connected() - Function to check connection status
208 * @pHddStaCtx: pointer to global HDD Station context
209 *
210 * Return: false if any errors encountered, true otherwise
211 */
212bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
213{
214 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
215}
216
217/**
218 * hdd_conn_get_connected_band() - get current connection radio band
219 * @pHddStaCtx: pointer to global HDD Station context
220 *
221 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
222 * eCSR_BAND_ALL if not connected
223 */
224eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
225{
226 uint8_t staChannel = 0;
227
228 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
229 staChannel = pHddStaCtx->conn_info.operationChannel;
230
231 if (staChannel > 0 && staChannel < 14)
232 return eCSR_BAND_24;
233 else if (staChannel >= 36 && staChannel <= 184)
234 return eCSR_BAND_5G;
235 else /* If station is not connected return as eCSR_BAND_ALL */
236 return eCSR_BAND_ALL;
237}
238
239/**
240 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
241 * @pHddStaCtx: pointer to global HDD Station context
242 * @pConnectedCipherAlgo: pointer to connected cipher algo
243 *
244 * Return: false if any errors encountered, true otherwise
245 */
246static inline bool
247hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
248 eCsrEncryptionType *pConnectedCipherAlgo)
249{
250 bool fConnected = false;
251
252 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
253
254 if (pConnectedCipherAlgo)
255 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
256
257 return fConnected;
258}
259
260/**
261 * hdd_conn_get_connected_bss_type() - get current bss type
262 * @pHddStaCtx: pointer to global HDD Station context
263 * @pConnectedBssType: pointer to connected bss type
264 *
265 * Return: false if any errors encountered, true otherwise
266 */
267inline bool
268hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
269 eMib_dot11DesiredBssType *pConnectedBssType)
270{
271 bool fConnected = false;
272
273 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
274
275 if (pConnectedBssType) {
276 *pConnectedBssType =
277 pHddStaCtx->conn_info.connDot11DesiredBssType;
278 }
279
280 return fConnected;
281}
282
283/**
284 * hdd_conn_save_connected_bss_type() - set connected bss type
285 * @pHddStaCtx: pointer to global HDD Station context
286 * @csr_roamBssType: bss type
287 *
288 * Return: none
289 */
290static inline void
291hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
292 eCsrRoamBssType csr_roamBssType)
293{
294 switch (csr_roamBssType) {
295 case eCSR_BSS_TYPE_INFRASTRUCTURE:
296 pHddStaCtx->conn_info.connDot11DesiredBssType =
297 eMib_dot11DesiredBssType_infrastructure;
298 break;
299
300 case eCSR_BSS_TYPE_IBSS:
301 case eCSR_BSS_TYPE_START_IBSS:
302 pHddStaCtx->conn_info.connDot11DesiredBssType =
303 eMib_dot11DesiredBssType_independent;
304 break;
305
306 /** We will never set the BssType to 'any' when attempting a connection
307 so CSR should never send this back to us.*/
308 case eCSR_BSS_TYPE_ANY:
309 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530310 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800311 break;
312 }
313}
314
315/**
316 * hdd_conn_save_connect_info() - save current connection information
317 * @pAdapter: pointer to adapter
318 * @pRoamInfo: pointer to roam info
319 * @eBssType: bss type
320 *
321 * Return: none
322 */
323static void
324hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
325 eCsrRoamBssType eBssType)
326{
327 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
328 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
329
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530330 QDF_ASSERT(pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331
332 if (pRoamInfo) {
333 /* Save the BSSID for the connection */
334 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530335 QDF_ASSERT(pRoamInfo->pBssDesc);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530336 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800337 &pRoamInfo->bssid);
338
339 /*
340 * Save the Station ID for this station from
341 * the 'Roam Info'. For IBSS mode, staId is
342 * assigned in NEW_PEER_IND. For reassoc,
343 * the staID doesn't change and it may be invalid
344 * in this structure so no change here.
345 */
346 if (!pRoamInfo->fReassocReq) {
347 pHddStaCtx->conn_info.staId[0] =
348 pRoamInfo->staId;
349 }
350 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530351 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800352 &pRoamInfo->bssid);
353 } else {
354 /*
355 * can't happen. We need a valid IBSS or Infra setting
356 * in the BSSDescription or we can't function.
357 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530358 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359 }
360
361 /* notify WMM */
362 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
363
364 if (!pRoamInfo->u.pConnectedProfile) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530365 QDF_ASSERT(pRoamInfo->u.pConnectedProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800366 } else {
367 /* Get Multicast Encryption Type */
368 encryptType =
369 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
370 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
371 /* Get Unicast Encryption Type */
372 encryptType =
373 pRoamInfo->u.pConnectedProfile->EncryptionType;
374 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
375
376 pHddStaCtx->conn_info.authType =
377 pRoamInfo->u.pConnectedProfile->AuthType;
378
379 pHddStaCtx->conn_info.operationChannel =
380 pRoamInfo->u.pConnectedProfile->operationChannel;
381
382 /* Save the ssid for the connection */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530383 qdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 &pRoamInfo->u.pConnectedProfile->SSID,
385 sizeof(tSirMacSSid));
386
387 /* Save dot11mode in which STA associated to AP */
388 pHddStaCtx->conn_info.dot11Mode =
389 pRoamInfo->u.pConnectedProfile->dot11Mode;
390
391 pHddStaCtx->conn_info.proxyARPService =
392 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530393
394 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
395
396 pHddStaCtx->conn_info.rate_flags =
397 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 }
399 }
400 /* save the connected BssType */
401 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
402}
403
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404/**
405 * hdd_send_ft_assoc_response() - send fast transition assoc response
406 * @dev: pointer to net device
407 * @pAdapter: pointer to adapter
408 * @pCsrRoamInfo: pointer to roam info
409 *
410 * Send the 11R key information to the supplicant. Only then can the supplicant
411 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
412 * for the same purpose.)
413 *
414 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
415 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
416 * This is the Assoc Response.
417 *
418 * Return: none
419 */
420static void
421hdd_send_ft_assoc_response(struct net_device *dev,
422 hdd_adapter_t *pAdapter,
423 tCsrRoamInfo *pCsrRoamInfo)
424{
425 union iwreq_data wrqu;
426 char *buff;
427 unsigned int len = 0;
428 u8 *pFTAssocRsp = NULL;
429
430 if (pCsrRoamInfo->nAssocRspLength == 0) {
431 hddLog(LOGE,
432 FL("pCsrRoamInfo->nAssocRspLength=%d"),
433 (int)pCsrRoamInfo->nAssocRspLength);
434 return;
435 }
436
437 pFTAssocRsp =
438 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
439 pCsrRoamInfo->nAssocReqLength);
440 if (pFTAssocRsp == NULL) {
441 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
442 return;
443 }
444 /* pFTAssocRsp needs to point to the IEs */
445 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
446 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
447 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
448
449 /* We need to send the IEs to the supplicant. */
450 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
451 if (buff == NULL) {
452 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
453 return;
454 }
455 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
456 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
457 wrqu.data.length = len;
458 memset(buff, 0, IW_GENERIC_IE_MAX);
459 memcpy(buff, pFTAssocRsp, len);
460 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
461
462 kfree(buff);
463}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800465/**
466 * hdd_send_ft_event() - send fast transition event
467 * @pAdapter: pointer to adapter
468 *
469 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
470 * FT events to the supplicant. At the reception of Auth2 we send the RIC
471 * followed by the auth response IEs to the supplicant.
472 * Once both are received in the supplicant, an FT event is generated
473 * to the supplicant.
474 *
475 * Return: none
476 */
477static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
478{
479 uint16_t auth_resp_len = 0;
480 uint32_t ric_ies_length = 0;
481 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
482
483#if defined(KERNEL_SUPPORT_11R_CFG80211)
484 struct cfg80211_ft_event_params ftEvent;
485 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
486 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
487 struct net_device *dev = pAdapter->dev;
488#else
489 char *buff;
490 union iwreq_data wrqu;
491 uint16_t str_len;
492#endif
493
494#if defined(KERNEL_SUPPORT_11R_CFG80211)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530495 qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
496 qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800497
498 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
499 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
500 if (ric_ies_length == 0) {
501 hddLog(LOGW,
502 FL("RIC IEs is of length 0 not sending RIC Information for now"));
503 }
504
505 ftEvent.ric_ies = ricIe;
506 ftEvent.ric_ies_len = ric_ies_length;
507 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
508
509 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
510 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
511 &auth_resp_len);
512
513 if (auth_resp_len == 0) {
514 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
515 return;
516 }
517
518 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
519
520 ftEvent.target_ap = ftIe;
521
Anurag Chouhan6d760662016-02-20 16:05:43 +0530522 ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
523 ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524
525 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
526 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
527 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
528 ftEvent.target_ap[0], ftEvent.target_ap[1],
529 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
530 ftEvent.target_ap[5]);
531
532 (void)cfg80211_ft_event(dev, &ftEvent);
533
534#else
535 /* We need to send the IEs to the supplicant */
536 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
537 if (buff == NULL) {
538 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
539 return;
540 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530541 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800542
543 /* Sme needs to send the RIC IEs first */
544 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
545 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
546 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
547 &ric_ies_length);
548 if (ric_ies_length == 0) {
549 hddLog(LOGW,
550 FL("RIC IEs is of length 0 not sending RIC Information for now"));
551 } else {
552 wrqu.data.length = str_len + ric_ies_length;
553 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
554 }
555
556 /* Sme needs to provide the Auth Resp */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530557 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800558 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
559 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
560 (u8 *) &buff[str_len],
561 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
562
563 if (auth_resp_len == 0) {
564 kfree(buff);
565 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
566 return;
567 }
568
569 wrqu.data.length = str_len + auth_resp_len;
570 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
571
572 kfree(buff);
573#endif
574}
575
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576#ifdef FEATURE_WLAN_ESE
577/**
578 * hdd_send_new_ap_channel_info() - send new ap channel info
579 * @dev: pointer to net device
580 * @pAdapter: pointer to adapter
581 * @pCsrRoamInfo: pointer to roam info
582 *
583 * Send the ESE required "new AP Channel info" to the supplicant.
584 * (This keeps the supplicant "up to date" on the current channel.)
585 *
586 * The current (new AP) channel information is passed in.
587 *
588 * Return: none
589 */
590static void
591hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
592 tCsrRoamInfo *pCsrRoamInfo)
593{
594 union iwreq_data wrqu;
595 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
596
597 if (descriptor == NULL) {
598 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
599 return;
600 }
601 /*
602 * Send the Channel event, the supplicant needs this to generate
603 * the Adjacent AP report.
604 */
605 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
606 descriptor->channelId);
607 memset(&wrqu, '\0', sizeof(wrqu));
608 wrqu.freq.m = descriptor->channelId;
609 wrqu.freq.e = 0;
610 wrqu.freq.i = 0;
611 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
612}
613
614#endif /* FEATURE_WLAN_ESE */
615
616/**
617 * hdd_send_update_beacon_ies_event() - send update beacons ie event
618 * @pAdapter: pointer to adapter
619 * @pCsrRoamInfo: pointer to roam info
620 *
621 * Return: none
622 */
623static void
624hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
625 tCsrRoamInfo *pCsrRoamInfo)
626{
627 union iwreq_data wrqu;
628 u8 *pBeaconIes;
629 u8 currentLen = 0;
630 char *buff;
631 int totalIeLen = 0, currentOffset = 0, strLen;
632
633 memset(&wrqu, '\0', sizeof(wrqu));
634
635 if (0 == pCsrRoamInfo->nBeaconLength) {
636 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
637 return;
638 }
639 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
640 if (pBeaconIes == NULL) {
641 hddLog(LOGW, FL("Beacon IEs is NULL"));
642 return;
643 }
644 /* pBeaconIes needs to point to the IEs */
645 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
646 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
647 hddLog(LOG1, FL("Beacon IEs length = %d"),
648 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
649
650 /* We need to send the IEs to the supplicant. */
651 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
652 if (buff == NULL) {
653 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
654 return;
655 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530656 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800657
658 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
659 currentLen = strLen + 1;
660
661 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
662 do {
663 /*
664 * If the beacon size exceeds max CUSTOM event size, break it
665 * into chunks of CUSTOM event max size and send it to
666 * supplicant. Changes are done in supplicant to handle this.
667 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530668 qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800669 currentLen =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530670 QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530671 qdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800672 currentLen);
673 currentOffset += currentLen;
674 totalIeLen -= currentLen;
675 wrqu.data.length = strLen + 1 + currentLen;
676 if (totalIeLen)
677 buff[strLen] = 1; /* more chunks pending */
678 else
679 buff[strLen] = 0; /* last chunk */
680
681 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
682 currentLen);
683 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
684 } while (totalIeLen > 0);
685
686 kfree(buff);
687}
688
689/**
690 * hdd_send_association_event() - send association event
691 * @dev: pointer to net device
692 * @pCsrRoamInfo: pointer to roam info
693 *
694 * Return: none
695 */
696static void hdd_send_association_event(struct net_device *dev,
697 tCsrRoamInfo *pCsrRoamInfo)
698{
699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
700 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
701 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
702 union iwreq_data wrqu;
703 int we_event;
704 char *msg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530705 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800706
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800707 /* Added to find the auth type on the fly at run time */
708 /* rather than with cfg to see if FT is enabled */
709 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
710 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800711
712 memset(&wrqu, '\0', sizeof(wrqu));
713 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
714 we_event = SIOCGIWAP;
715#ifdef WLAN_FEATURE_ROAM_OFFLOAD
716 if (NULL != pCsrRoamInfo)
717 if (pCsrRoamInfo->roamSynchInProgress)
718 /* change logging before release */
719 hddLog(LOG4, "LFR3:hdd_send_association_event");
720#endif
721 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
722 if (!pCsrRoamInfo) {
723 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
724 return;
725 }
726
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800727 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
728 cds_incr_active_session(pAdapter->device_mode,
729 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800730 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
731 sizeof(pCsrRoamInfo->pBssDesc->bssId));
732
733#ifdef WLAN_FEATURE_P2P_DEBUG
734 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
735 if (global_p2p_connection_status ==
736 P2P_CLIENT_CONNECTING_STATE_1) {
737 global_p2p_connection_status =
738 P2P_CLIENT_CONNECTED_STATE_1;
739 hddLog(LOGE,
740 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
741 } else if (global_p2p_connection_status ==
742 P2P_CLIENT_CONNECTING_STATE_2) {
743 global_p2p_connection_status =
744 P2P_CLIENT_COMPLETED_STATE;
745 hddLog(LOGE,
746 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
747 }
748 }
749#endif
750 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
751 MAC_ADDRESS_STR "\n",
752 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
753 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
754 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
755
756 /*
757 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
758 * is Enabled Or Send IWEVASSOCRESPIE Event if
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -0800759 * fFTEnable is true.
760 * Send FT Keys to the supplicant when FT is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800761 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762 if ((pRoamProfile->AuthType.authType[0] ==
763 eCSR_AUTH_TYPE_FT_RSN_PSK)
764 || (pRoamProfile->AuthType.authType[0] ==
765 eCSR_AUTH_TYPE_FT_RSN)
766#ifdef FEATURE_WLAN_ESE
767 || (pRoamProfile->AuthType.authType[0] ==
768 eCSR_AUTH_TYPE_CCKM_RSN)
769 || (pRoamProfile->AuthType.authType[0] ==
770 eCSR_AUTH_TYPE_CCKM_WPA)
771#endif
772 ) {
773 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
774 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800775 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
776 tSirSmeChanInfo chan_info;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530777 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 &pHddStaCtx->conn_info.bssId);
779 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
780 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
781 chan_info.info = pCsrRoamInfo->chan_info.info;
782 chan_info.band_center_freq1 =
783 pCsrRoamInfo->chan_info.band_center_freq1;
784 chan_info.band_center_freq2 =
785 pCsrRoamInfo->chan_info.band_center_freq2;
786 chan_info.reg_info_1 =
787 pCsrRoamInfo->chan_info.reg_info_1;
788 chan_info.reg_info_2 =
789 pCsrRoamInfo->chan_info.reg_info_2;
790
791 /* send peer status indication to oem app */
792 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
793 ePeerConnected,
794 pCsrRoamInfo->
795 timingMeasCap,
796 pAdapter->sessionId,
797 &chan_info);
798 }
799#ifdef MSM_PLATFORM
800#ifdef CONFIG_CNSS
801 /* start timer in sta/p2p_cli */
802 spin_lock_bh(&pHddCtx->bus_bw_lock);
803 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
804 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
805 spin_unlock_bh(&pHddCtx->bus_bw_lock);
806 hdd_start_bus_bw_compute_timer(pAdapter);
807#endif
808#endif
809 } else if (eConnectionState_IbssConnected == /* IBss Associated */
810 pHddStaCtx->conn_info.connState) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800811 cds_update_connection_info(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800812 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
813 ETH_ALEN);
814 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
815 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
816 } else { /* Not Associated */
817
818 pr_info("wlan: disconnected\n");
819 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +0530820 cds_decr_session_set_pcl(pAdapter->device_mode,
821 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800823
824#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
825 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
826#endif
827
828 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530829 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800830 &pHddStaCtx->conn_info.bssId);
831
832 /* send peer status indication to oem app */
833 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
834 ePeerDisconnected, 0,
835 pAdapter->sessionId,
836 NULL);
837 }
838#ifdef WLAN_FEATURE_LPSS
839 pAdapter->rssi_send = false;
840 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
841#endif
842#ifdef FEATURE_WLAN_TDLS
843 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) &&
844 (pCsrRoamInfo)) {
845 hddLog(LOG4,
846 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
847 pCsrRoamInfo->tdls_prohibited,
848 pCsrRoamInfo->tdls_chan_swit_prohibited);
849
850 wlan_hdd_update_tdls_info(pAdapter,
851 pCsrRoamInfo->tdls_prohibited,
852 pCsrRoamInfo->tdls_chan_swit_prohibited);
853 }
854#endif
855#ifdef MSM_PLATFORM
856 /* stop timer in sta/p2p_cli */
857 spin_lock_bh(&pHddCtx->bus_bw_lock);
858 pAdapter->prev_tx_packets = 0;
859 pAdapter->prev_rx_packets = 0;
860 spin_unlock_bh(&pHddCtx->bus_bw_lock);
861 hdd_stop_bus_bw_compute_timer(pAdapter);
862#endif
863 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800864 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865 /* Send SCC/MCC Switching event to IPA */
866 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
867
868 msg = NULL;
869 /*During the WLAN uninitialization,supplicant is stopped before the
870 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800871 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872 wireless_send_event(dev, we_event, &wrqu, msg);
873#ifdef FEATURE_WLAN_ESE
874 if (eConnectionState_Associated ==
875 pHddStaCtx->conn_info.connState) {
876 if ((pRoamProfile->AuthType.authType[0] ==
877 eCSR_AUTH_TYPE_CCKM_RSN) ||
878 (pRoamProfile->AuthType.authType[0] ==
879 eCSR_AUTH_TYPE_CCKM_WPA))
880 hdd_send_new_ap_channel_info(dev, pAdapter,
881 pCsrRoamInfo);
882 }
883#endif
884 }
885}
886
887/**
888 * hdd_conn_remove_connect_info() - remove connection info
889 * @pHddStaCtx: pointer to global HDD station context
890 * @pCsrRoamInfo: pointer to roam info
891 *
892 * Return: none
893 */
894static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
895{
896 /* Remove staId, bssId and peerMacAddress */
897 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530898 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
899 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530900 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901
902 /* Clear all security settings */
903 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
904 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
905 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
906
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530907 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
908 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909
910 /* Set not-connected state */
911 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
912 pHddStaCtx->conn_info.proxyARPService = 0;
913
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530914 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800915}
916
917/**
918 * hdd_roam_deregister_sta() - deregister station
919 * @pAdapter: pointer to adapter
920 * @staId: station identifier
921 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530922 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800923 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530924static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
926{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530927 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800928 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
929
930 if (eConnectionState_IbssDisconnected ==
931 pHddStaCtx->conn_info.connState) {
932 /*
933 * Do not set the carrier off when the last peer leaves.
934 * We will set the carrier off while stopping the IBSS.
935 */
936 }
937
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530938 qdf_status = ol_txrx_clear_peer(staId);
939 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 hddLog(LOGE,
941 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530942 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800943 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530944 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800945}
946
947/**
948 * hdd_dis_connect_handler() - disconnect event handler
949 * @pAdapter: pointer to adapter
950 * @pRoamInfo: pointer to roam info
951 * @roamId: roam identifier
952 * @roamStatus: roam status
953 * @roamResult: roam result
954 *
955 * This function handles disconnect event:
956 * 1. Disable transmit queues;
957 * 2. Clean up internal connection states and data structures;
958 * 3. Send disconnect indication to supplicant.
959 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530960 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530962static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 tCsrRoamInfo *pRoamInfo,
964 uint32_t roamId,
965 eRoamCmdStatus roamStatus,
966 eCsrRoamResult roamResult)
967{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530968 QDF_STATUS status = QDF_STATUS_SUCCESS;
969 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800970 struct net_device *dev = pAdapter->dev;
971 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
972 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
973 uint8_t sta_id;
974 bool sendDisconInd = true;
975
976 if (dev == NULL) {
977 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530978 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800979 }
980 /* notify apps that we can't pass traffic anymore */
981 hddLog(LOG1, FL("Disabling queues"));
982 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
983 WLAN_CONTROL_PATH);
984
985 if (hdd_ipa_is_enabled(pHddCtx))
986 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
987 WLAN_STA_DISCONNECT,
988 pHddStaCtx->conn_info.bssId.bytes);
989
990#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
991 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
992#endif
993
994#ifdef QCA_PKT_PROTO_TRACE
995 /* STA disconnected, update into trace buffer */
996 if (pHddCtx->config->gEnableDebugLog)
997 cds_pkt_trace_buf_update("ST:DISASC");
998#endif /* QCA_PKT_PROTO_TRACE */
999
1000 /* HDD has initiated disconnect, do not send disconnect indication
1001 * to kernel. Sending disconnected event to kernel for userspace
1002 * initiated disconnect will be handled by hdd_DisConnectHandler call
1003 * to cfg80211_disconnected.
1004 */
1005 if ((eConnectionState_Disconnecting ==
1006 pHddStaCtx->conn_info.connState) ||
1007 (eConnectionState_NotConnected ==
1008 pHddStaCtx->conn_info.connState)) {
1009 hddLog(LOG1,
1010 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1011 sendDisconInd = false;
1012 }
1013
1014 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1015 INIT_COMPLETION(pAdapter->disconnect_comp_var);
1016 hddLog(LOG1,
1017 FL("Set HDD connState to eConnectionState_Disconnecting"));
1018 hdd_conn_set_connection_state(pAdapter,
1019 eConnectionState_Disconnecting);
1020 }
1021
1022 hdd_clear_roam_profile_ie(pAdapter);
1023 hdd_wmm_init(pAdapter);
1024
1025 /* indicate 'disconnect' status to wpa_supplicant... */
1026 hdd_send_association_event(dev, pRoamInfo);
1027 /* indicate disconnected event to nl80211 */
1028 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1029 /*
1030 * Only send indication to kernel if not initiated
1031 * by kernel
1032 */
1033 if (sendDisconInd) {
1034 /*
1035 * To avoid wpa_supplicant sending "HANGED" CMD
1036 * to ICS UI.
1037 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001038 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1039 if (pRoamInfo->reasonCode ==
1040 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1041 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001042 cfg80211_disconnected(dev, pRoamInfo->
Ryan Hsua335c162016-01-21 12:12:20 -08001043 reasonCode, NULL, 0,
1044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1045 true,
1046#endif
1047 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001048 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001049 cfg80211_disconnected(dev,
Ryan Hsua335c162016-01-21 12:12:20 -08001050 WLAN_REASON_UNSPECIFIED, NULL, 0,
1051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1052 true,
1053#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001055 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001056
1057 hdd_info("sent disconnected event to nl80211, rssi: %d",
1058 pAdapter->rssi);
1059 }
1060 /*
1061 * During the WLAN uninitialization,supplicant is stopped
1062 * before the driver so not sending the status of the
1063 * connection to supplicant.
1064 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001065 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001066#ifdef WLAN_FEATURE_P2P_DEBUG
1067 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1068 if (global_p2p_connection_status ==
1069 P2P_CLIENT_CONNECTED_STATE_1) {
1070 global_p2p_connection_status =
1071 P2P_CLIENT_DISCONNECTED_STATE;
1072 hddLog(LOGE,
1073 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1074 } else if (global_p2p_connection_status ==
1075 P2P_CLIENT_COMPLETED_STATE) {
1076 global_p2p_connection_status =
1077 P2P_NOT_ACTIVE;
1078 hddLog(LOGE,
1079 "[P2P State] P2P Client is removed and moved to inactive state");
1080 }
1081 }
1082#endif
1083
1084 }
1085 }
1086
1087 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001088 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001089 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301090 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301091 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001092 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301093 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301094 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1095 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301096 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001097 }
1098 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301099 /* Clear all the peer sta register with TL. */
1100 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1101 if (0 == pHddStaCtx->conn_info.staId[i])
1102 continue;
1103 sta_id = pHddStaCtx->conn_info.staId[i];
1104 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1105 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301106 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301107 hddLog(LOGE,
1108 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1109 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301110 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301111 }
1112 /* set the staid and peer mac as 0, all other
1113 * reset are done in hdd_connRemoveConnectInfo.
1114 */
1115 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301116 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301117 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301118 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1119 pHddCtx->sta_to_adapter[sta_id] = NULL;
1120 }
1121 } else {
1122 sta_id = pHddStaCtx->conn_info.staId[0];
1123 /* We should clear all sta register with TL,
1124 * for now, only one.
1125 */
1126 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301127 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301128 hddLog(LOGE,
1129 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1130 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301131 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301132 }
1133 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001134 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001135 /* Clear saved connection information in HDD */
1136 hdd_conn_remove_connect_info(pHddStaCtx);
1137 hddLog(LOG1, FL("Set HDD connState to eConnectionState_NotConnected"));
1138 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1139#ifdef WLAN_FEATURE_GTK_OFFLOAD
1140 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1141 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1142 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1143 sizeof(tSirGtkOffloadParams));
1144 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1145 }
1146#endif
1147
1148#ifdef FEATURE_WLAN_TDLS
1149 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1150 wlan_hdd_tdls_disconnection_callback(pAdapter);
1151#endif
1152
1153 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1154 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1155 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1156 (pAdapter),
1157 pAdapter->sessionId);
1158 }
1159 /* Unblock anyone waiting for disconnect to complete */
1160 complete(&pAdapter->disconnect_comp_var);
1161 return status;
1162}
1163
1164/**
1165 * hdd_set_peer_authorized_event() - set peer_authorized_event
1166 * @vdev_id: vdevid
1167 *
1168 * Return: None
1169 */
1170void hdd_set_peer_authorized_event(uint32_t vdev_id)
1171{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301172 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001173 hdd_adapter_t *adapter = NULL;
1174
1175 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1176 if (adapter == NULL) {
1177 hddLog(LOGE,
1178 "%s: Invalid vdev_id", __func__);
1179 }
1180 complete(&adapter->sta_authorized_event);
1181}
1182
1183/**
1184 * hdd_change_peer_state() - change peer state
1185 * @pAdapter: HDD adapter
1186 * @sta_state: peer state
1187 * @roam_synch_in_progress: roam synch in progress
1188 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301189 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001190 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301191QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001192 uint8_t sta_id,
1193 enum ol_txrx_peer_state sta_state,
1194 bool roam_synch_in_progress)
1195{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301196 QDF_STATUS err;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001197 uint8_t *peer_mac_addr;
Manjunathappa Prakash2593a642016-04-01 08:53:35 -07001198 struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001199 ol_txrx_vdev_handle vdev;
1200 ol_txrx_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201
1202 if (!pdev) {
1203 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301204 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 }
1206
1207 if (sta_id >= WLAN_MAX_STA_COUNT) {
1208 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301209 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210 }
1211
1212 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1213 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301214 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001215
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001216 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1217 if (peer_mac_addr == NULL) {
1218 hddLog(LOGE, "peer mac addr is NULL");
1219 return QDF_STATUS_E_FAULT;
1220 }
1221
1222 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301223 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001224 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301225 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001226 }
1227#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1228 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301229 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230#endif
1231
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001232 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1234 /* make sure event is reset */
1235 INIT_COMPLETION(pAdapter->sta_authorized_event);
1236#endif
1237
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001238 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001239 hdd_set_peer_authorized_event,
1240 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301241 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001242 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301243 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001244 }
1245
1246 if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1247 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1248#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
1249 unsigned long rc;
1250
1251 /* wait for event from firmware to set the event */
1252 rc = wait_for_completion_timeout(
1253 &pAdapter->sta_authorized_event,
1254 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1255 if (!rc) {
1256 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1257 __func__);
1258 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001259 vdev = ol_txrx_get_vdev_for_peer(peer);
1260 ol_txrx_vdev_unpause(vdev,
1261 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262#endif
1263 }
1264 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301265 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266}
1267
1268/**
1269 * hdd_roam_register_sta() - register station
1270 * @pAdapter: pointer to adapter
1271 * @pRoamInfo: pointer to roam info
1272 * @staId: station identifier
1273 * @pPeerMacAddress: peer MAC address
1274 * @pBssDesc: pointer to BSS description
1275 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301276 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001277 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301278static QDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279 tCsrRoamInfo *pRoamInfo,
1280 uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301281 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001282 tSirBssDescription *pBssDesc)
1283{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301284 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001285 struct ol_txrx_desc_type staDesc = { 0 };
1286 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Dhanashri Atre182b0272016-02-17 15:35:07 -08001287 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001288
1289 if (NULL == pBssDesc)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301290 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001291
1292 /* Get the Station ID from the one saved during the association */
1293 staDesc.sta_id = staId;
1294
1295 /* set the QoS field appropriately */
1296 if (hdd_wmm_is_active(pAdapter))
1297 staDesc.is_qos_enabled = 1;
1298 else
1299 staDesc.is_qos_enabled = 0;
1300
1301#ifdef FEATURE_WLAN_WAPI
1302 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1303 pAdapter->wapi_info.fIsWapiSta);
1304 if (pAdapter->wapi_info.fIsWapiSta)
1305 staDesc.is_wapi_supported = 1;
1306 else
1307 staDesc.is_wapi_supported = 0;
1308#endif /* FEATURE_WLAN_WAPI */
1309
Dhanashri Atre50141c52016-04-07 13:15:29 -07001310 /* Register the vdev transmit and receive functions */
1311 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
1312 txrx_ops.rx.rx = hdd_rx_packet_cbk;
1313 ol_txrx_vdev_register(
1314 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
1315 pAdapter, &txrx_ops);
1316 pAdapter->tx_fn = txrx_ops.tx.tx;
1317
Dhanashri Atre182b0272016-02-17 15:35:07 -08001318 qdf_status = ol_txrx_register_peer(&staDesc);
1319
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301320 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001321 hddLog(LOGW,
1322 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301323 qdf_status, qdf_status);
1324 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325 }
1326
1327 if (!pRoamInfo->fAuthRequired) {
1328 /*
1329 * Connections that do not need Upper layer auth, transition
1330 * TLSHIM directly to 'Authenticated' state
1331 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301332 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001333 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001334 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001335#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1336 pRoamInfo->roamSynchInProgress
1337#else
1338 false
1339#endif
1340 );
1341
1342 hdd_conn_set_authenticated(pAdapter, true);
1343 } else {
1344 hddLog(LOG3,
1345 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1346 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301347 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001349 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001350#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1351 pRoamInfo->roamSynchInProgress
1352#else
1353 false
1354#endif
1355 );
1356 hdd_conn_set_authenticated(pAdapter, false);
1357 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301358 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001359}
1360
1361/**
1362 * hdd_send_re_assoc_event() - send reassoc event
1363 * @dev: pointer to net device
1364 * @pAdapter: pointer to adapter
1365 * @pCsrRoamInfo: pointer to roam info
1366 * @reqRsnIe: pointer to RSN Information element
1367 * @reqRsnLength: length of RSN IE
1368 *
1369 * Return: none
1370 */
1371static void hdd_send_re_assoc_event(struct net_device *dev,
1372 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1373 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1374{
1375 unsigned int len = 0;
1376 u8 *pFTAssocRsp = NULL;
1377 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001378 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001379 uint32_t rspRsnLength = 0;
1380 struct ieee80211_channel *chan;
1381 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1382 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1383 uint8_t *buf_ptr, ssid_ie_len;
1384 struct cfg80211_bss *bss = NULL;
1385 uint8_t *final_req_ie = NULL;
1386 tCsrRoamConnectedProfile roam_profile;
1387 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1388
1389 if (!rspRsnIe) {
1390 hddLog(LOGE, FL("Unable to allocate RSN IE"));
Naveen Rawatdafda292016-01-06 18:32:14 -08001391 goto done;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001392 }
1393
Naveen Rawat14298b92015-11-25 16:27:41 -08001394 if (!assoc_req_ies) {
1395 hdd_err("Unable to allocate Assoc Req IE");
Naveen Rawatdafda292016-01-06 18:32:14 -08001396 goto done;
Naveen Rawat14298b92015-11-25 16:27:41 -08001397 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001398 if (pCsrRoamInfo == NULL) {
1399 hddLog(LOGE, FL("Invalid CSR roam info"));
1400 goto done;
1401 }
1402
1403 if (pCsrRoamInfo->nAssocRspLength == 0) {
1404 hddLog(LOGE, FL("Invalid assoc response length"));
1405 goto done;
1406 }
1407
1408 pFTAssocRsp =
1409 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1410 pCsrRoamInfo->nAssocReqLength);
1411 if (pFTAssocRsp == NULL)
1412 goto done;
1413
1414 /* pFTAssocRsp needs to point to the IEs */
1415 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1416 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1417 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1418
1419 /*
1420 * Active session count is decremented upon disconnection, but during
1421 * roaming, there is no disconnect indication and hence active session
1422 * count is not decremented.
1423 * After roaming is completed, active session count is incremented
1424 * as a part of connect indication but effectively after roaming the
1425 * active session count should still be the same and hence upon
1426 * successful reassoc decrement the active session count here.
1427 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001428 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +05301429 cds_decr_session_set_pcl(pAdapter->device_mode,
1430 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431
1432 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1433 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1434 rspRsnLength = len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301435 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1436 qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437
1438 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1439 (int)pCsrRoamInfo->pBssDesc->channelId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301440 qdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001441 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1442 &roam_profile);
1443 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1444 pCsrRoamInfo->bssid.bytes,
1445 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
Ryan Hsu535d16a2016-01-18 16:45:12 -08001446#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001447 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
Ryan Hsu535d16a2016-01-18 16:45:12 -08001448#else
1449 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
1450#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451
1452 if (bss == NULL)
1453 hddLog(LOGE, FL("Get BSS returned NULL"));
1454 buf_ptr = buf_ssid_ie;
1455 *buf_ptr = SIR_MAC_SSID_EID;
1456 buf_ptr++;
1457 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1458 buf_ptr++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301459 qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001460 roam_profile.SSID.length);
1461 ssid_ie_len = 2 + roam_profile.SSID.length;
Jeff Johnson9991f472016-01-06 16:02:31 -08001462 hdd_notice("SSIDIE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301463 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001464 buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1466 if (final_req_ie == NULL)
1467 goto done;
1468 buf_ptr = final_req_ie;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301469 qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001470 buf_ptr += ssid_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301471 qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1472 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1473 qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
Jeff Johnson9991f472016-01-06 16:02:31 -08001475 hdd_notice("Req RSN IE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301476 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001477 final_req_ie, (ssid_ie_len + reqRsnLength));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001478 cfg80211_roamed_bss(dev, bss,
1479 final_req_ie, (ssid_ie_len + reqRsnLength),
1480 rspRsnIe, rspRsnLength, GFP_KERNEL);
1481
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301482 qdf_mem_copy(assoc_req_ies,
Naveen Rawat14298b92015-11-25 16:27:41 -08001483 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1484 pCsrRoamInfo->nAssocReqLength);
1485
1486 hdd_notice("ReAssoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301487 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001488 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1489
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001490 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001491 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1492 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001493 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494done:
Naveen Rawatdf0a7e72016-01-06 18:35:53 -08001495 sme_roam_free_connect_profile(&roam_profile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496 if (final_req_ie)
1497 kfree(final_req_ie);
1498 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001499 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001500}
1501
1502/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301503 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001504 * @roaminfo - Roaming Information
Govind Singhedc5cda2015-10-23 17:11:35 +05301505 *
1506 * Return: roam sync status if roaming offloaded else false
1507 */
1508#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001509bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
Govind Singhedc5cda2015-10-23 17:11:35 +05301510{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001511 if (roaminfo)
1512 return roaminfo->roamSynchInProgress;
1513 else
1514 return false;
Govind Singhedc5cda2015-10-23 17:11:35 +05301515}
1516#endif
1517
1518
1519/**
1520 * hdd_change_sta_state_authenticated()-
1521 * This function changes STA state to authenticated
1522 * @adapter: pointer to the adapter structure.
1523 * @roaminfo: pointer to the RoamInfo structure.
1524 *
1525 * This is called from hdd_RoamSetKeyCompleteHandler
1526 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1527 *
1528 * Return: 0 on success and errno on failure
1529 */
1530static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1531 tCsrRoamInfo *roaminfo)
1532{
1533 int ret;
1534 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1535
1536 hddLog(LOG1,
1537 "Changing TL state to AUTHENTICATED for StaId= %d",
1538 hddstactx->conn_info.staId[0]);
1539
1540 /* Connections that do not need Upper layer authentication,
1541 * transition TL to 'Authenticated' state after the keys are set
1542 */
1543 ret = hdd_change_peer_state(adapter,
1544 hddstactx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001545 OL_TXRX_PEER_STATE_AUTH,
Govind Singhedc5cda2015-10-23 17:11:35 +05301546 hdd_is_roam_sync_in_progress(roaminfo));
1547 hdd_conn_set_authenticated(adapter, true);
1548 if ((WLAN_HDD_INFRA_STATION == adapter->device_mode) ||
1549 (WLAN_HDD_P2P_CLIENT == adapter->device_mode)) {
1550 sme_ps_enable_auto_ps_timer(
1551 WLAN_HDD_GET_HAL_CTX(adapter),
1552 adapter->sessionId,
1553 hddstactx->hdd_ReassocScenario);
1554 }
1555
1556 return ret;
1557}
1558
1559/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001560 * hdd_roam_set_key_complete_handler() - Update the security parameters
1561 * @pAdapter: pointer to adapter
1562 * @pRoamInfo: pointer to roam info
1563 * @roamId: roam id
1564 * @roamStatus: roam status
1565 * @roamResult: roam result
1566 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301567 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001568 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301569static QDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 tCsrRoamInfo *pRoamInfo,
1571 uint32_t roamId,
1572 eRoamCmdStatus roamStatus,
1573 eCsrRoamResult roamResult)
1574{
1575 eCsrEncryptionType connectedCipherAlgo;
1576 bool fConnected = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301577 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001578 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1579 ENTER();
1580
1581 if (NULL == pRoamInfo) {
1582 hddLog(LOG2, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301583 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 }
1585 /*
1586 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1587 * then go to 'authenticated'. For all other authentication types
1588 * (those that do not require upper layer authentication) we can put TL
1589 * directly into 'authenticated' state.
1590 */
1591 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1592 MAC_ADDRESS_STR, roamStatus, roamResult,
1593 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1594
1595 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1596 &connectedCipherAlgo);
1597 if (fConnected) {
1598 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
1599 uint8_t staId;
1600
Anurag Chouhanc5548422016-02-24 18:33:27 +05301601 if (qdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001602 pHddStaCtx->roam_info.roamingState =
1603 HDD_ROAM_STATE_NONE;
1604 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301605 qdf_status = hdd_ibss_get_sta_id(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001606 pHddStaCtx,
1607 &pRoamInfo->peerMac,
1608 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301609 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610 hddLog(LOG2,
1611 "WLAN TL STA Ptk Installed for STAID=%d",
1612 staId);
1613 pHddStaCtx->roam_info.roamingState =
1614 HDD_ROAM_STATE_NONE;
1615 }
1616 }
1617 } else {
1618 /*
1619 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301620 * HDD later.This routine is invoked twice.
1621 * 1)set PTK 2)set GTK.The following if
1622 * statement will be TRUE when setting GTK.
1623 * At this time we don't handle the state in detail.
1624 * Related CR: 174048 - TL not in authenticated state
1625 */
1626 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult)
1627 pHddStaCtx->conn_info.gtk_installed = true;
1628 else
1629 pHddStaCtx->conn_info.ptk_installed = true;
1630
1631 /* In WPA case move STA to authenticated when
1632 * ptk is installed.Earlier in WEP case STA
1633 * was moved to AUTHENTICATED prior to setting
1634 * the unicast key and it was resulting in sending
1635 * few un-encrypted packet. Now in WEP case
1636 * STA state will be moved to AUTHENTICATED
1637 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001638 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301639 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1640 eCSR_ENCRYPT_TYPE_WEP40) ||
1641 (pHddStaCtx->conn_info.ucEncryptionType ==
1642 eCSR_ENCRYPT_TYPE_WEP104) ||
1643 (pHddStaCtx->conn_info.ucEncryptionType ==
1644 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1645 (pHddStaCtx->conn_info.ucEncryptionType ==
1646 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1647 if (pHddStaCtx->conn_info.gtk_installed &&
1648 pHddStaCtx->conn_info.ptk_installed)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301649 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301650 hdd_change_sta_state_authenticated(pAdapter,
1651 pRoamInfo);
1652 } else if (pHddStaCtx->conn_info.ptk_installed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301653 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301654 hdd_change_sta_state_authenticated(pAdapter,
1655 pRoamInfo);
1656 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657
Govind Singhedc5cda2015-10-23 17:11:35 +05301658 if (pHddStaCtx->conn_info.gtk_installed &&
1659 pHddStaCtx->conn_info.ptk_installed) {
1660 pHddStaCtx->conn_info.gtk_installed = false;
1661 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662 }
1663
1664 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301665 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001666 }
1667 } else {
1668 /*
1669 * possible disassoc after issuing set key and waiting
1670 * set key complete.
1671 */
1672 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1673 }
1674
1675 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301676 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677}
1678
1679/**
1680 * hdd_perform_roam_set_key_complete() - perform set key complete
1681 * @pAdapter: pointer to adapter
1682 *
1683 * Return: none
1684 */
1685void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1686{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301687 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1689 tCsrRoamInfo roamInfo;
1690 roamInfo.fAuthRequired = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301691 qdf_mem_copy(roamInfo.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301692 pHddStaCtx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301693 qdf_mem_copy(roamInfo.peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301694 pHddStaCtx->roam_info.peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001695
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301696 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001697 hdd_roam_set_key_complete_handler(pAdapter,
1698 &roamInfo,
1699 pHddStaCtx->roam_info.roamId,
1700 pHddStaCtx->roam_info.roamStatus,
1701 eCSR_ROAM_RESULT_AUTHENTICATED);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301702 if (qdf_ret_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001703 hddLog(LOGE, FL("Set Key complete failure"));
1704
1705 pHddStaCtx->roam_info.deferKeyComplete = false;
1706}
1707
1708/**
1709 * hdd_association_completion_handler() - association completion handler
1710 * @pAdapter: pointer to adapter
1711 * @pRoamInfo: pointer to roam info
1712 * @roamId: roam id
1713 * @roamStatus: roam status
1714 * @roamResult: roam result
1715 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301716 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301718static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 tCsrRoamInfo *pRoamInfo,
1720 uint32_t roamId,
1721 eRoamCmdStatus roamStatus,
1722 eCsrRoamResult roamResult)
1723{
1724 struct net_device *dev = pAdapter->dev;
1725 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1726 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301727 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001728 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1729 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 int ft_carrier_on = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001731 bool hddDisconInProgress = false;
1732 unsigned long rc;
1733
1734 if (!pHddCtx) {
1735 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301736 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001737 }
1738
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739 /* HDD has initiated disconnect, do not send connect result indication
1740 * to kernel as it will be handled by __cfg80211_disconnect.
1741 */
1742 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1743 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1744 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1745 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1746 hddDisconInProgress = true;
1747 }
1748
1749 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1750 if (NULL == pRoamInfo) {
1751 hddLog(LOGE, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301752 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753 }
1754 if (!hddDisconInProgress) {
1755 hddLog(LOG1, FL("Set HDD connState to eConnectionState_Associated"));
1756 hdd_conn_set_connection_state(pAdapter,
1757 eConnectionState_Associated);
1758 }
1759 /* Save the connection info from CSR... */
1760 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1761 eCSR_BSS_TYPE_INFRASTRUCTURE);
1762#ifdef FEATURE_WLAN_WAPI
1763 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1764 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1765 || pRoamInfo->u.pConnectedProfile->AuthType ==
1766 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1767 pAdapter->wapi_info.fIsWapiSta = 1;
1768 } else {
1769 pAdapter->wapi_info.fIsWapiSta = 0;
1770 }
1771#endif /* FEATURE_WLAN_WAPI */
1772
1773 /* Indicate 'connect' status to user space */
1774 hdd_send_association_event(dev, pRoamInfo);
1775
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001776 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001777 if (pHddCtx->miracast_value)
1778 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1779 }
1780
1781 /* Initialize the Linkup event completion variable */
1782 INIT_COMPLETION(pAdapter->linkup_event_var);
1783
1784 /*
1785 * Sometimes Switching ON the Carrier is taking time to activate
1786 * the device properly. Before allowing any packet to go up to
1787 * the application, device activation has to be ensured for
1788 * proper queue mapping by the kernel. we have registered net
1789 * device notifier for device change notification. With this we
1790 * will come to know that the device is getting
1791 * activated properly.
1792 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001793 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001794 /*
1795 * Enable Linkup Event Servicing which allows the net
1796 * device notifier to set the linkup event variable.
1797 */
1798 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001799
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001800 /* Switch on the Carrier to activate the device */
1801 wlan_hdd_netif_queue_control(pAdapter,
1802 WLAN_NETIF_CARRIER_ON,
1803 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001805 /*
1806 * Wait for the Link to up to ensure all the queues
1807 * are set properly by the kernel.
1808 */
1809 rc = wait_for_completion_timeout(
1810 &pAdapter->linkup_event_var,
1811 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1812 );
1813 if (!rc)
1814 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001815
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001816 /*
1817 * Disable Linkup Event Servicing - no more service
1818 * required from the net device notifier call.
1819 */
1820 pAdapter->isLinkUpSvcNeeded = false;
1821 } else {
1822 pHddStaCtx->ft_carrier_on = false;
1823 ft_carrier_on = true;
1824 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001825 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1826 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1827 else
1828 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1829 pRoamInfo->staId);
1830
1831 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1832
1833 if (hdd_ipa_is_enabled(pHddCtx))
1834 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1835 WLAN_STA_CONNECT,
1836 pRoamInfo->bssid.bytes);
1837
1838#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1839 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1840#endif
1841
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001842 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001843 pAdapter);
1844
1845#ifdef FEATURE_WLAN_TDLS
1846 wlan_hdd_tdls_connection_callback(pAdapter);
1847#endif
1848
1849#ifdef QCA_PKT_PROTO_TRACE
1850 /* STA Associated, update into trace buffer */
1851 if (pHddCtx->config->gEnableDebugLog)
1852 cds_pkt_trace_buf_update("ST:ASSOC");
1853#endif /* QCA_PKT_PROTO_TRACE */
1854 /*
1855 * For reassoc, the station is already registered, all we need
1856 * is to change the state of the STA in TL.
1857 * If authentication is required (WPA/WPA2/DWEP), change TL to
1858 * CONNECTED instead of AUTHENTICATED.
1859 */
1860 if (!pRoamInfo->fReassocReq) {
1861 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001862 u8 *pFTAssocRsp = NULL;
1863 unsigned int assocRsplen = 0;
1864 u8 *pFTAssocReq = NULL;
1865 unsigned int assocReqlen = 0;
1866 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001867 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1868 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1869
1870 /* add bss_id to cfg80211 data base */
1871 bss =
1872 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1873 pRoamInfo);
1874 if (NULL == bss) {
1875 pr_err("wlan: Not able to create BSS entry\n");
1876 wlan_hdd_netif_queue_control(pAdapter,
1877 WLAN_NETIF_CARRIER_OFF,
1878 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301879 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001880 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001881 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1882 eCSR_AUTH_TYPE_FT_RSN
1883 || pRoamInfo->u.pConnectedProfile->AuthType ==
1884 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1885
1886 /* Association Response */
1887 pFTAssocRsp =
1888 (u8 *) (pRoamInfo->pbFrames +
1889 pRoamInfo->nBeaconLength +
1890 pRoamInfo->nAssocReqLength);
1891 if (pFTAssocRsp != NULL) {
1892 /*
1893 * pFTAssocRsp needs to point to the IEs
1894 */
1895 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1896 hddLog(LOG1,
1897 FL("AssocRsp is now at %02x%02x"),
1898 (unsigned int)pFTAssocRsp[0],
1899 (unsigned int)pFTAssocRsp[1]);
1900 assocRsplen =
1901 pRoamInfo->nAssocRspLength -
1902 FT_ASSOC_RSP_IES_OFFSET;
1903 } else {
1904 hddLog(LOGE, FL("AssocRsp is NULL"));
1905 assocRsplen = 0;
1906 }
1907
1908 /* Association Request */
1909 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1910 pRoamInfo->nBeaconLength);
1911 if (pFTAssocReq != NULL) {
1912 if (!ft_carrier_on) {
1913 /*
1914 * pFTAssocReq needs to point to
1915 * the IEs
1916 */
1917 pFTAssocReq +=
1918 FT_ASSOC_REQ_IES_OFFSET;
1919 hddLog(LOG1,
1920 FL("pFTAssocReq is now at %02x%02x"),
1921 (unsigned int)
1922 pFTAssocReq[0],
1923 (unsigned int)
1924 pFTAssocReq[1]);
1925 assocReqlen =
1926 pRoamInfo->nAssocReqLength -
1927 FT_ASSOC_REQ_IES_OFFSET;
1928 } else {
1929 /*
1930 * This should contain only the
1931 * FTIEs
1932 */
1933 assocReqlen =
1934 pRoamInfo->nAssocReqLength;
1935 }
1936 } else {
1937 hddLog(LOGE, FL("AssocReq is NULL"));
1938 assocReqlen = 0;
1939 }
1940
1941 if (ft_carrier_on) {
1942 if (!hddDisconInProgress) {
1943 /*
1944 * After roaming is completed,
1945 * active session count is
1946 * incremented as a part of
1947 * connect indication but
1948 * effectively the active
1949 * session count should still
1950 * be the same and hence upon
1951 * successful reassoc
1952 * decrement the active session
1953 * count here.
1954 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001955 if (!hdd_is_roam_sync_in_progress
1956 (pRoamInfo))
1957 cds_decr_session_set_pcl
1958 (pAdapter->device_mode,
1959 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001960 hddLog(LOG1,
1961 FL("ft_carrier_on is %d, sending roamed indication"),
1962 ft_carrier_on);
1963 chan =
1964 ieee80211_get_channel
1965 (pAdapter->wdev.wiphy,
1966 (int)pRoamInfo->pBssDesc->
1967 channelId);
1968 hddLog(LOG1,
1969 "assocReqlen %d assocRsplen %d",
1970 assocReqlen,
1971 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08001972
1973 hdd_notice(
1974 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301975 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05301976 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301977 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001978 pFTAssocReq,
1979 assocReqlen);
1980
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981 cfg80211_roamed(dev, chan,
1982 pRoamInfo->
1983 bssid.bytes,
1984 pFTAssocReq,
1985 assocReqlen,
1986 pFTAssocRsp,
1987 assocRsplen,
1988 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001989 wlan_hdd_send_roam_auth_event(
1990 pHddCtx,
1991 pRoamInfo->bssid.bytes,
1992 pFTAssocReq,
1993 assocReqlen,
1994 pFTAssocRsp,
1995 assocRsplen,
1996 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001997 }
1998 if (sme_get_ftptk_state
1999 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2000 pAdapter->sessionId)) {
2001 sme_set_ftptk_state
2002 (WLAN_HDD_GET_HAL_CTX
2003 (pAdapter),
2004 pAdapter->sessionId,
2005 false);
2006 pRoamInfo->fAuthRequired =
2007 false;
2008
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302009 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002010 roam_info.bssid,
2011 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302012 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302013 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014 roam_info.peerMac,
2015 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302016 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002017 pHddStaCtx->roam_info.roamId =
2018 roamId;
2019 pHddStaCtx->roam_info.
2020 roamStatus = roamStatus;
2021 pHddStaCtx->roam_info.
2022 deferKeyComplete = true;
2023 }
2024 } else if (!hddDisconInProgress) {
2025 hddLog(LOG1,
2026 FL("ft_carrier_on is %d, sending connect indication"),
2027 ft_carrier_on);
2028 cfg80211_connect_result(dev,
2029 pRoamInfo->
2030 bssid.bytes,
2031 pFTAssocReq,
2032 assocReqlen,
2033 pFTAssocRsp,
2034 assocRsplen,
2035 WLAN_STATUS_SUCCESS,
2036 GFP_KERNEL);
2037 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002038 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002039 /*
2040 * wpa supplicant expecting WPA/RSN IE in
2041 * connect result.
2042 */
2043 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2044 (pAdapter),
2045 pAdapter->sessionId,
2046 &reqRsnLength,
2047 reqRsnIe);
2048
2049 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2050 (pAdapter),
2051 pAdapter->sessionId,
2052 &rspRsnLength,
2053 rspRsnIe);
2054 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002055 if (ft_carrier_on)
2056 hdd_send_re_assoc_event(dev,
2057 pAdapter,
2058 pRoamInfo,
2059 reqRsnIe,
2060 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002061 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002062 hddLog(LOG1,
2063 FL("sending connect indication to nl80211:for bssid "
2064 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302065 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002066 MAC_ADDR_ARRAY
2067 (pRoamInfo->bssid.bytes),
2068 roamResult, roamStatus);
2069
2070 /* inform connect result to nl80211 */
2071 cfg80211_connect_result(dev,
2072 pRoamInfo->
2073 bssid.bytes,
2074 reqRsnIe,
2075 reqRsnLength,
2076 rspRsnIe,
2077 rspRsnLength,
2078 WLAN_STATUS_SUCCESS,
2079 GFP_KERNEL);
2080 }
2081 }
2082 }
2083 if (!hddDisconInProgress) {
2084 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002085 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086 bss);
2087
2088 /*
2089 * Perform any WMM-related association
2090 * processing.
2091 */
2092 hdd_wmm_assoc(pAdapter, pRoamInfo,
2093 eCSR_BSS_TYPE_INFRASTRUCTURE);
2094
2095 /*
2096 * Start the Queue - Start tx queues before
2097 * hdd_roam_register_sta, since
2098 * hdd_roam_register_sta will flush any cached
2099 * data frames immediately.
2100 */
2101 hddLog(LOG1, FL("Enabling queues"));
2102 wlan_hdd_netif_queue_control(pAdapter,
2103 WLAN_WAKE_ALL_NETIF_QUEUE,
2104 WLAN_CONTROL_PATH);
2105
2106 /*
2107 * Register the Station with TL after associated
2108 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302109 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002110 pRoamInfo,
2111 pHddStaCtx->
2112 conn_info.
2113 staId[0],
2114 NULL,
2115 pRoamInfo->
2116 pBssDesc);
2117 }
2118 } else {
2119 /*
2120 * wpa supplicant expecting WPA/RSN IE in connect result
2121 * in case of reassociation also need to indicate it to
2122 * supplicant.
2123 */
2124 csr_roam_get_wpa_rsn_req_ie(
2125 WLAN_HDD_GET_HAL_CTX(pAdapter),
2126 pAdapter->sessionId,
2127 &reqRsnLength, reqRsnIe);
2128
2129 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2130 reqRsnIe, reqRsnLength);
2131 /* Reassoc successfully */
2132 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302133 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002134 hdd_change_peer_state(pAdapter,
2135 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002136 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002137#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2138 pRoamInfo->roamSynchInProgress
2139#else
2140 false
2141#endif
2142 );
2143 hdd_conn_set_authenticated(pAdapter, false);
2144 } else {
2145 hddLog(LOG2,
2146 FL("staId: %d Changing TL state to AUTHENTICATED"),
2147 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302148 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 hdd_change_peer_state(pAdapter,
2150 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002151 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002152#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2153 pRoamInfo->roamSynchInProgress
2154#else
2155 false
2156#endif
2157 );
2158 hdd_conn_set_authenticated(pAdapter, true);
2159 }
2160
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302161 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002162 /*
2163 * Perform any WMM-related association
2164 * processing
2165 */
2166 hdd_wmm_assoc(pAdapter, pRoamInfo,
2167 eCSR_BSS_TYPE_INFRASTRUCTURE);
2168 }
2169
2170 /* Start the tx queues */
2171#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2172 if (pRoamInfo->roamSynchInProgress)
2173 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2174#endif
2175 hddLog(LOG1, FL("Enabling queues"));
2176 wlan_hdd_netif_queue_control(pAdapter,
2177 WLAN_WAKE_ALL_NETIF_QUEUE,
2178 WLAN_CONTROL_PATH);
2179 }
2180
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302181 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182 hddLog(LOGE,
2183 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302184 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185 }
2186#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302187 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002188 sizeof(pAdapter->hdd_stats.hddPmfStats));
2189#endif
2190 } else {
2191 hdd_wext_state_t *pWextState =
2192 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2193 if (pRoamInfo)
2194 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302195 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2197 roamResult, roamStatus);
2198 else
2199 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302200 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002201 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2202 roamResult, roamStatus);
2203
2204 /*
2205 * CR465478: Only send up a connection failure result when CSR
2206 * has completed operation - with a ASSOCIATION_FAILURE status.
2207 */
2208 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2209 && !hddDisconInProgress) {
2210 if (pRoamInfo)
2211 hddLog(LOGE,
2212 FL("send connect failure to nl80211: for bssid "
2213 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302214 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302216 roamResult, roamStatus,
2217 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002218 else
2219 hddLog(LOGE,
2220 FL("connect failed: for bssid "
2221 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302222 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2224 roamResult, roamStatus);
2225
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002226 /* inform association failure event to nl80211 */
2227 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2228 roamResult) {
2229 if (pRoamInfo)
2230 cfg80211_connect_result(dev,
2231 pRoamInfo->bssid.bytes,
2232 NULL, 0, NULL, 0,
2233 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2234 GFP_KERNEL);
2235 else
2236 cfg80211_connect_result(dev,
2237 pWextState->req_bssId.bytes,
2238 NULL, 0, NULL, 0,
2239 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2240 GFP_KERNEL);
2241 } else {
2242 if (pRoamInfo) {
2243 eCsrAuthType authType =
2244 pWextState->roamProfile.AuthType.
2245 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302246 eCsrEncryptionType encryption_type =
2247 pWextState->roamProfile.
2248 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002249 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302250 (((authType ==
2251 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002252 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302253 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2254 ((encryption_type ==
2255 eCSR_ENCRYPT_TYPE_WEP40) ||
2256 (encryption_type ==
2257 eCSR_ENCRYPT_TYPE_WEP104) ||
2258 (encryption_type ==
2259 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2260 (encryption_type ==
2261 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002262 /*
2263 * In case of OPEN-WEP or SHARED-WEP
2264 * authentication, send exact protocol
2265 * reason code. This enables user
2266 * applications to reconnect the station
2267 * with correct configuration.
2268 */
2269 cfg80211_connect_result(dev,
2270 pRoamInfo->bssid.bytes, NULL, 0,
2271 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302272 (isWep &&
2273 pRoamInfo->reasonCode) ?
2274 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002275 WLAN_STATUS_UNSPECIFIED_FAILURE,
2276 GFP_KERNEL);
2277 } else
2278 cfg80211_connect_result(dev,
2279 pWextState->req_bssId.bytes,
2280 NULL, 0, NULL, 0,
2281 WLAN_STATUS_UNSPECIFIED_FAILURE,
2282 GFP_KERNEL);
2283 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302284 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002285 }
2286
2287 if (pRoamInfo) {
2288 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2289 pRoamInfo->statusCode)
2290 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2291 pRoamInfo->statusCode)
2292 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2293 pRoamInfo->statusCode)) {
2294 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2295 pRoamInfo);
2296 }
2297 }
2298
2299 /*
2300 * Set connection state to eConnectionState_NotConnected only
2301 * when CSR has completed operation - with a
2302 * ASSOCIATION_FAILURE status.
2303 */
2304 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2305 && !hddDisconInProgress) {
2306 hddLog(LOG1,
2307 FL("state to eConnectionState_NotConnected"));
2308 hdd_conn_set_connection_state(pAdapter,
2309 eConnectionState_NotConnected);
2310 }
2311 hdd_wmm_init(pAdapter);
2312
2313 hddLog(LOG1, FL("Disabling queues"));
2314 wlan_hdd_netif_queue_control(pAdapter,
2315 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2316 WLAN_CONTROL_PATH);
2317 }
2318
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302319 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002320 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302321 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002322
Govind Singh24db1ed2015-12-18 15:54:59 +05302323 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2324 cds_force_sap_on_scc(roamResult,
2325 pRoamInfo->pBssDesc->channelId);
2326 } else {
2327 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302328 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302329 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002330
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302331 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002332}
2333
2334/**
2335 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2336 * @pAdapter: pointer to adapter
2337 * @pRoamInfo: pointer to roam info
2338 * @roamId: roam id
2339 * @roamStatus: roam status
2340 * @roamResult: roam result
2341 *
2342 * Here we update the status of the Ibss when we receive information that we
2343 * have started/joined an ibss session.
2344 *
2345 * Return: none
2346 */
2347static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2348 tCsrRoamInfo *pRoamInfo,
2349 uint32_t roamId,
2350 eRoamCmdStatus roamStatus,
2351 eCsrRoamResult roamResult)
2352{
2353 hddLog(LOG1, "%s: id %d, status %d, result %d",
2354 pAdapter->dev->name, roamId, roamStatus, roamResult);
2355
2356 switch (roamResult) {
2357 /* both IBSS Started and IBSS Join should come in here. */
2358 case eCSR_ROAM_RESULT_IBSS_STARTED:
2359 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2360 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2361 {
2362 hdd_context_t *pHddCtx =
2363 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302364 hdd_station_ctx_t *hdd_sta_ctx =
2365 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302366 struct qdf_mac_addr broadcastMacAddr =
2367 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002368
2369 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302370 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002371 return;
2372 }
2373
2374 /* When IBSS Started comes from CSR, we need to move
2375 * connection state to IBSS Disconnected (meaning no peers
2376 * are in the IBSS).
2377 */
2378 hddLog(LOG1,
2379 FL("Set HDD connState to eConnectionState_IbssDisconnected"));
2380 hdd_conn_set_connection_state(pAdapter,
2381 eConnectionState_IbssDisconnected);
2382 /* notify wmm */
2383 hdd_wmm_connect(pAdapter, pRoamInfo,
2384 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302385
2386 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2387
2388 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002389 pAdapter;
2390 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302391 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392 &broadcastMacAddr,
2393 pRoamInfo->pBssDesc);
2394
2395 if (pRoamInfo->pBssDesc) {
2396 struct cfg80211_bss *bss;
2397#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2398 struct ieee80211_channel *chan;
2399 int chan_no;
2400 unsigned int freq;
2401#endif
2402 /* we created the IBSS, notify supplicant */
2403 hddLog(LOG1,
2404 FL("%s: created ibss " MAC_ADDRESS_STR),
2405 pAdapter->dev->name,
2406 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2407
2408 /* we must first give cfg80211 the BSS information */
2409 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2410 pRoamInfo);
2411 if (NULL == bss) {
2412 hddLog(LOGE,
2413 FL("%s: unable to create IBSS entry"),
2414 pAdapter->dev->name);
2415 return;
2416 }
2417 hddLog(LOG1, FL("Enabling queues"));
2418 wlan_hdd_netif_queue_control(pAdapter,
2419 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2420 WLAN_CONTROL_PATH);
2421
2422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2423 chan_no = pRoamInfo->pBssDesc->channelId;
2424
2425 if (chan_no <= 14)
2426 freq = ieee80211_channel_to_frequency(chan_no,
2427 IEEE80211_BAND_2GHZ);
2428 else
2429 freq = ieee80211_channel_to_frequency(chan_no,
2430 IEEE80211_BAND_5GHZ);
2431
2432 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2433
2434 if (chan)
2435 cfg80211_ibss_joined(pAdapter->dev,
2436 bss->bssid, chan,
2437 GFP_KERNEL);
2438 else
2439 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2440 pAdapter->dev->name,
2441 (int)pRoamInfo->pBssDesc->channelId);
2442#else
2443 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2444 GFP_KERNEL);
2445#endif
2446 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002447 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002448 bss);
2449 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002450 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002451 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002452 pAdapter->sessionId);
2453 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2454 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002455 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002456 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002457 break;
2458 }
2459
2460 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2461 {
2462 hddLog(LOGE,
2463 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2464 break;
2465 }
2466
2467 default:
2468 hddLog(LOGE, FL("%s: unexpected result %d"),
2469 pAdapter->dev->name, (int)roamResult);
2470 break;
2471 }
2472
2473 return;
2474}
2475
2476/**
2477 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2478 * @pHddStaCtx: pointer to global HDD station context
2479 * @staId: station id
2480 * @peerMacAddress: pointer to peer MAC address
2481 *
2482 * This information is passed to iwconfig later. The peer that joined
2483 * last is passed as information to iwconfig.
2484 *
2485 * Return:
2486 * true if we add MAX_IBSS_PEERS or less STA
2487 * false otherwise.
2488 */
2489static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302490 struct qdf_mac_addr *peerMacAddress)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002491{
2492 bool fSuccess = false;
2493 int idx = 0;
2494
2495 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2496 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2497 pHddStaCtx->conn_info.staId[idx] = staId;
2498
Anurag Chouhanc5548422016-02-24 18:33:27 +05302499 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002500 peerMacAddress[idx], peerMacAddress);
2501
2502 fSuccess = true;
2503 break;
2504 }
2505 }
2506
2507 return fSuccess;
2508}
2509
2510/**
2511 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2512 * @pAdapter: pointer to adapter
2513 * @staId: station id
2514 *
2515 * Return:
2516 * true if we remove MAX_IBSS_PEERS or less STA
2517 * false otherwise.
2518 */
2519static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2520{
2521 bool fSuccess = false;
2522 int idx = 0;
2523 uint8_t valid_idx = 0;
2524 uint8_t del_idx = 0;
2525 uint8_t empty_slots = 0;
2526 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2527
2528 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2529 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2530 pHddStaCtx->conn_info.staId[idx] = 0;
2531
Anurag Chouhanc5548422016-02-24 18:33:27 +05302532 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002533 peerMacAddress[idx]);
2534
2535 fSuccess = true;
2536
2537 /*
2538 * Note the deleted Index, if its 0 we need special
2539 * handling.
2540 */
2541 del_idx = idx;
2542
2543 empty_slots++;
2544 } else {
2545 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2546 valid_idx = idx;
2547 } else {
2548 /* Found an empty slot */
2549 empty_slots++;
2550 }
2551 }
2552 }
2553
2554 if (MAX_IBSS_PEERS == empty_slots) {
2555 /* Last peer departed, set the IBSS state appropriately */
2556 pHddStaCtx->conn_info.connState =
2557 eConnectionState_IbssDisconnected;
2558 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2559 }
2560 /* Find next active staId, to have a valid sta trigger for TL. */
2561 if (fSuccess == true) {
2562 if (del_idx == 0) {
2563 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2564 pHddStaCtx->conn_info.staId[0] =
2565 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302566 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002567 peerMacAddress[0],
2568 &pHddStaCtx->conn_info.
2569 peerMacAddress[valid_idx]);
2570
2571 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302572 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002573 peerMacAddress[valid_idx]);
2574 }
2575 }
2576 }
2577 return fSuccess;
2578}
2579
2580/**
2581 * roam_ibss_connect_handler() - IBSS connection handler
2582 * @pAdapter: pointer to adapter
2583 * @pRoamInfo: pointer to roam info
2584 *
2585 * We update the status of the IBSS to connected in this function.
2586 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302587 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002588 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302589static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002590 tCsrRoamInfo *pRoamInfo)
2591{
2592 struct cfg80211_bss *bss;
2593 hddLog(LOG1, FL("IBSS Connect Indication from SME. Set HDD connState to eConnectionState_IbssConnected"));
2594 /*
2595 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2596 * a partner stations).
2597 */
2598 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2599
2600 /* Save the connection info from CSR... */
2601 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2602
2603 /* Send the bssid address to the wext. */
2604 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2605 /* add bss_id to cfg80211 data base */
2606 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2607 if (NULL == bss) {
2608 hddLog(LOGE,
2609 FL("%s: unable to create IBSS entry"),
2610 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302611 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002612 }
2613 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002615 bss);
2616
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302617 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002618}
2619
2620/**
2621 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2622 * @pAdapter: pointer to adapter
2623 * @pRoamInfo: pointer to roam info
2624 * @roamId: roam id
2625 * @roamStatus: roam status
2626 * @roamResult: roam result
2627 *
2628 * This function indicates the Mic failure to the supplicant
2629 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302630 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002631 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302632static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002633hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2634 tCsrRoamInfo *pRoamInfo,
2635 uint32_t roamId,
2636 eRoamCmdStatus roamStatus,
2637 eCsrRoamResult roamResult)
2638{
2639 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2640
2641 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2642 TKIP_COUNTER_MEASURE_STOPED ==
2643 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2644 struct iw_michaelmicfailure msg;
2645 union iwreq_data wreq;
2646 memset(&msg, '\0', sizeof(msg));
2647 msg.src_addr.sa_family = ARPHRD_ETHER;
2648 memcpy(msg.src_addr.sa_data,
2649 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2650 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2651 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2652 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2653
2654 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2655 msg.flags = IW_MICFAILURE_GROUP;
2656 else
2657 msg.flags = IW_MICFAILURE_PAIRWISE;
2658 memset(&wreq, 0, sizeof(wreq));
2659 wreq.data.length = sizeof(msg);
2660 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2661 (char *)&msg);
2662 /* inform mic failure to nl80211 */
2663 cfg80211_michael_mic_failure(pAdapter->dev,
2664 pRoamInfo->u.pMICFailureInfo->
2665 taMacAddr,
2666 ((pRoamInfo->u.pMICFailureInfo->
2667 multicast ==
2668 eSIR_TRUE) ?
2669 NL80211_KEYTYPE_GROUP :
2670 NL80211_KEYTYPE_PAIRWISE),
2671 pRoamInfo->u.pMICFailureInfo->
2672 keyId,
2673 pRoamInfo->u.pMICFailureInfo->TSC,
2674 GFP_KERNEL);
2675
2676 }
2677
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302678 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002679}
2680
2681/**
2682 * roam_roam_connect_status_update_handler() - IBSS connect status update
2683 * @pAdapter: pointer to adapter
2684 * @pRoamInfo: pointer to roam info
2685 * @roamId: roam id
2686 * @roamStatus: roam status
2687 * @roamResult: roam result
2688 *
2689 * The Ibss connection status is updated regularly here in this function.
2690 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302691 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002692 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302693static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2695 tCsrRoamInfo *pRoamInfo,
2696 uint32_t roamId,
2697 eRoamCmdStatus roamStatus,
2698 eCsrRoamResult roamResult)
2699{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302700 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701
2702 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2703 switch (roamResult) {
2704 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2705 {
2706 hdd_station_ctx_t *pHddStaCtx =
2707 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2708 struct station_info staInfo;
2709
2710 pr_info("IBSS New Peer indication from SME "
2711 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2712 MAC_ADDRESS_STR " and stationID= %d",
2713 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2714 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2715 pRoamInfo->staId);
2716
2717 if (!roam_save_ibss_station
2718 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2719 pRoamInfo->staId,
2720 &pRoamInfo->peerMac)) {
2721 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2722 break;
2723 }
2724
2725 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2726
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002727 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302728 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729 pRoamInfo,
2730 pRoamInfo->staId,
2731 &pRoamInfo->peerMac,
2732 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302733 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002734 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302735 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2736 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002737 }
2738 pHddStaCtx->ibss_sta_generation++;
2739 memset(&staInfo, 0, sizeof(staInfo));
2740 staInfo.filled = 0;
2741 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2742
2743 cfg80211_new_sta(pAdapter->dev,
2744 (const u8 *)pRoamInfo->peerMac.bytes,
2745 &staInfo, GFP_KERNEL);
2746
2747 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2748 pHddStaCtx->ibss_enc_key.encType
2749 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2750 pHddStaCtx->ibss_enc_key.encType
2751 || eCSR_ENCRYPT_TYPE_TKIP ==
2752 pHddStaCtx->ibss_enc_key.encType
2753 || eCSR_ENCRYPT_TYPE_AES ==
2754 pHddStaCtx->ibss_enc_key.encType) {
2755 pHddStaCtx->ibss_enc_key.keyDirection =
2756 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302757 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002758 &pRoamInfo->peerMac);
2759
2760 hddLog(LOG2, "New peer joined set PTK encType=%d",
2761 pHddStaCtx->ibss_enc_key.encType);
2762
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302763 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002764 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2765 (pAdapter),
2766 pAdapter->sessionId,
2767 &pHddStaCtx->ibss_enc_key,
2768 &roamId);
2769
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302770 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002771 hddLog(LOGE,
2772 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302773 qdf_status);
2774 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002775 }
2776 }
2777 hddLog(LOG1, FL("Enabling queues"));
2778 wlan_hdd_netif_queue_control(pAdapter,
2779 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2780 WLAN_CONTROL_PATH);
2781 break;
2782 }
2783
2784 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2785 {
2786
2787 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2788
2789 break;
2790 }
2791 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2792 {
2793 hdd_station_ctx_t *pHddStaCtx =
2794 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2795
2796 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2797 hddLog(LOGW,
2798 "IBSS peer departed by cannot find peer in our registration table with TL");
2799
2800 pr_info("IBSS Peer Departed from SME "
2801 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2802 MAC_ADDRESS_STR " and stationID= %d",
2803 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2804 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2805 pRoamInfo->staId);
2806
2807 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2808
2809 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2810 pHddStaCtx->ibss_sta_generation++;
2811
2812 cfg80211_del_sta(pAdapter->dev,
2813 (const u8 *)&pRoamInfo->peerMac.bytes,
2814 GFP_KERNEL);
2815 break;
2816 }
2817 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2818 {
2819 hddLog(LOG3,
2820 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2821 /* Stop only when we are inactive */
2822 hddLog(LOG1, FL("Disabling queues"));
2823 wlan_hdd_netif_queue_control(pAdapter,
2824 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2825 WLAN_CONTROL_PATH);
2826 hddLog(LOG1,
2827 FL("Set HDD connState to eConnectionState_NotConnected"));
2828 hdd_conn_set_connection_state(pAdapter,
2829 eConnectionState_NotConnected);
2830
2831 /* Send the bssid address to the wext. */
2832 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2833 break;
2834 }
2835 default:
2836 break;
2837
2838 }
2839
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302840 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002841}
2842
2843#ifdef FEATURE_WLAN_TDLS
2844/**
2845 * hdd_roam_register_tdlssta() - register new TDLS station
2846 * @pAdapter: pointer to adapter
2847 * @peerMac: pointer to peer MAC address
2848 * @staId: station identifier
2849 * @ucastSig: unicast signature
2850 *
2851 * Construct the staDesc and register with TL the new STA.
2852 * This is called as part of ADD_STA in the TDLS setup.
2853 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302854 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002855 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302856QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002857 const uint8_t *peerMac, uint16_t staId,
2858 uint8_t ucastSig)
2859{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302860 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002861 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002862 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002863
2864 /*
2865 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2866 * be peer MAC, here we are working on direct Link
2867 */
2868 staDesc.sta_id = staId;
2869
2870 /* set the QoS field appropriately .. */
2871 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2872 : (staDesc.is_qos_enabled = 0);
2873
Dhanashri Atre50141c52016-04-07 13:15:29 -07002874 /* Register the vdev transmit and receive functions */
2875 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2876 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2877 ol_txrx_vdev_register(
2878 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2879 pAdapter, &txrx_ops);
2880 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002881
2882 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002883 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302884 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002885 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302886 qdf_status, qdf_status);
2887 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002888 }
2889
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302890 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002891}
2892
2893/**
2894 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2895 * @pAdapter: pointer to adapter
2896 * @staId: station identifier
2897 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302898 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002899 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302900static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002901 uint8_t staId)
2902{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302903 QDF_STATUS qdf_status;
2904 qdf_status = ol_txrx_clear_peer(staId);
2905 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002906 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302907 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002908 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302909 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002910}
2911
2912/**
2913 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2914 * @pAdapter: pointer to adapter
2915 * @pRoamInfo: pointer to roam info
2916 * @roamId: roam id
2917 * @roamStatus: roam status
2918 * @roamResult: roam result
2919 *
2920 * HDD interface between SME and TL to ensure TDLS client registration with
2921 * TL in case of new TDLS client is added and deregistration at the time
2922 * TDLS client is deleted.
2923 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302924 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002925 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302926static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002927hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
2928 tCsrRoamInfo *pRoamInfo,
2929 uint32_t roamId,
2930 eRoamCmdStatus roamStatus,
2931 eCsrRoamResult roamResult)
2932{
2933 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2934 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2935 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302936 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002937 uint8_t staIdx;
2938 hddTdlsPeer_t *curr_peer;
2939 uint32_t reason;
2940
2941 hddLog(LOG2,
2942 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
2943 roamResult ==
2944 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
2945 ==
2946 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
2947 roamResult ==
2948 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
2949 : roamResult ==
2950 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
2951 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
2952 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
2953 roamResult ==
2954 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
2955 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
2956 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
2957 : roamResult ==
2958 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
2959 : roamResult ==
2960 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
2961 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
2962 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
2963
2964 if (!pHddTdlsCtx) {
2965 hddLog(LOG1,
2966 FL("TDLS ctx is null, ignore roamResult (%d)"),
2967 roamResult);
2968 return status;
2969 }
2970
2971 switch (roamResult) {
2972 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
2973 {
2974 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
2975 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
2976 pRoamInfo->statusCode);
2977 } else {
2978 /*
2979 * Check if there is available index for this new TDLS
2980 * STA.
2981 */
2982 for (staIdx = 0;
2983 staIdx < pHddCtx->max_num_tdls_sta;
2984 staIdx++) {
2985 if (0 ==
2986 pHddCtx->tdlsConnInfo[staIdx].
2987 staId) {
2988 pHddCtx->tdlsConnInfo[staIdx].
2989 sessionId =
2990 pRoamInfo->sessionId;
2991 pHddCtx->tdlsConnInfo[staIdx].
2992 staId = pRoamInfo->staId;
2993
2994 hddLog(LOGW,
2995 ("TDLS: STA IDX at %d is %d "
2996 "of mac "
2997 MAC_ADDRESS_STR),
2998 staIdx,
2999 pHddCtx->
3000 tdlsConnInfo[staIdx].
3001 staId,
3002 MAC_ADDR_ARRAY
3003 (pRoamInfo->peerMac.bytes));
3004
Anurag Chouhanc5548422016-02-24 18:33:27 +05303005 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003006 tdlsConnInfo
3007 [staIdx].
3008 peerMac,
3009 &pRoamInfo->
3010 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303011 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003012 break;
3013 }
3014 }
3015 if (staIdx < pHddCtx->max_num_tdls_sta) {
3016 if (-1 ==
3017 wlan_hdd_tdls_set_sta_id(pAdapter,
3018 pRoamInfo->
3019 peerMac.bytes,
3020 pRoamInfo->
3021 staId)) {
3022 hddLog(LOGE,
3023 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303024 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003025 }
3026
3027 (WLAN_HDD_GET_CTX(pAdapter))->
3028 sta_to_adapter[pRoamInfo->staId] =
3029 pAdapter;
3030 /*
3031 * store the ucast signature,
3032 * if required for further reference.
3033 */
3034
3035 wlan_hdd_tdls_set_signature(pAdapter,
3036 pRoamInfo->
3037 peerMac.bytes,
3038 pRoamInfo->
3039 ucastSig);
3040 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303041 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003042 hddLog(LOGE,
3043 FL("no available slot in conn_info. staId %d cannot be stored"),
3044 pRoamInfo->staId);
3045 }
3046 pAdapter->tdlsAddStaStatus = status;
3047 }
3048 complete(&pAdapter->tdls_add_station_comp);
3049 break;
3050 }
3051 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3052 {
3053 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3054 hddLog(LOGE,
3055 FL("Add Sta failed. status code(=%d)"),
3056 pRoamInfo->statusCode);
3057 }
3058 /* store the ucast signature which will be used later when
3059 * registering to TL
3060 */
3061 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3062 complete(&pAdapter->tdls_add_station_comp);
3063 break;
3064 }
3065 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3066 {
3067 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3068 hddLog(LOGE,
3069 FL("Link Establish Request failed. status(=%d)"),
3070 pRoamInfo->statusCode);
3071 }
3072 complete(&pAdapter->tdls_link_establish_req_comp);
3073 break;
3074 }
3075 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3076 {
3077 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3078 staIdx++) {
3079 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3080 pRoamInfo->sessionId)
3081 && pRoamInfo->staId ==
3082 pHddCtx->tdlsConnInfo[staIdx].staId) {
3083 hddLog(LOGW,
3084 ("HDD: del STA IDX = %x"),
3085 pRoamInfo->staId);
3086
3087 curr_peer =
3088 wlan_hdd_tdls_find_peer(pAdapter,
3089 pRoamInfo->
3090 peerMac.bytes,
3091 true);
3092 if (NULL != curr_peer
3093 && TDLS_IS_CONNECTED(curr_peer)) {
3094 hdd_roam_deregister_tdlssta
3095 (pAdapter,
3096 pRoamInfo->staId);
3097 wlan_hdd_tdls_decrement_peer_count
3098 (pAdapter);
3099 }
3100 wlan_hdd_tdls_reset_peer(pAdapter,
3101 pRoamInfo->
3102 peerMac.bytes);
3103
3104 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3105 pHddCtx->tdlsConnInfo[staIdx].
3106 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303107 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003108 tdlsConnInfo[staIdx].
3109 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303110 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303111 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003112 break;
3113 }
3114 }
3115 complete(&pAdapter->tdls_del_station_comp);
3116 }
3117 break;
3118 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3119 {
3120 hddLog(LOGE,
3121 FL("Sending teardown to supplicant with reason code %u"),
3122 pRoamInfo->reasonCode);
3123
3124 curr_peer =
3125 wlan_hdd_tdls_find_peer(pAdapter,
3126 pRoamInfo->peerMac.bytes, true);
3127 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3128 pRoamInfo->reasonCode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303129 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003130 break;
3131 }
3132 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3133 {
3134 /* 0 staIdx is assigned to AP we dont want to touch that */
3135 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3136 staIdx++) {
3137 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3138 pRoamInfo->sessionId)
3139 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3140 hddLog(LOGW,
3141 ("hdd_tdlsStatusUpdate: staIdx %d "
3142 MAC_ADDRESS_STR),
3143 pHddCtx->tdlsConnInfo[staIdx].
3144 staId,
3145 MAC_ADDR_ARRAY(pHddCtx->
3146 tdlsConnInfo
3147 [staIdx].
3148 peerMac.
3149 bytes));
3150 wlan_hdd_tdls_reset_peer(pAdapter,
3151 pHddCtx->
3152 tdlsConnInfo
3153 [staIdx].
3154 peerMac.bytes);
3155 hdd_roam_deregister_tdlssta(pAdapter,
3156 pHddCtx->
3157 tdlsConnInfo
3158 [staIdx].
3159 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303160 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003161 sizeof
3162 (smeTdlsPeerStateParams));
3163 smeTdlsPeerStateParams.vdevId =
3164 pHddCtx->tdlsConnInfo[staIdx].
3165 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303166 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003167 peerMacAddr,
3168 &pHddCtx->
3169 tdlsConnInfo[staIdx].
3170 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303171 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003172 smeTdlsPeerStateParams.peerState =
3173 eSME_TDLS_PEER_STATE_TEARDOWN;
3174
3175 hddLog(LOG1,
3176 FL("calling sme_update_tdls_peer_state for staIdx %d "
3177 MAC_ADDRESS_STR),
3178 pHddCtx->tdlsConnInfo[staIdx].
3179 staId,
3180 MAC_ADDR_ARRAY(pHddCtx->
3181 tdlsConnInfo
3182 [staIdx].
3183 peerMac.
3184 bytes));
3185 status =
3186 sme_update_tdls_peer_state(
3187 pHddCtx->hHal,
3188 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303189 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003190 hddLog(LOGE,
3191 FL("sme_update_tdls_peer_state failed for "
3192 MAC_ADDRESS_STR),
3193 MAC_ADDR_ARRAY
3194 (pHddCtx->
3195 tdlsConnInfo[staIdx].
3196 peerMac.bytes));
3197 }
3198 wlan_hdd_tdls_decrement_peer_count
3199 (pAdapter);
3200
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303201 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003202 tdlsConnInfo[staIdx].
3203 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303204 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003205 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3206 pHddCtx->tdlsConnInfo[staIdx].
3207 sessionId = 255;
3208
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303209 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003210 }
3211 }
3212 break;
3213 }
3214 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3215 {
3216 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303217 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3218 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219 hddLog(LOG2,
3220 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3221 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303222 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303223 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003224 break;
3225 }
3226
3227 curr_peer =
3228 wlan_hdd_tdls_get_peer(pAdapter,
3229 pRoamInfo->peerMac.bytes);
3230 if (!curr_peer) {
3231 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303232 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003233 } else {
3234 if (eTDLS_LINK_CONNECTED ==
3235 curr_peer->link_status) {
3236 hddLog(LOGE,
3237 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3238 } else {
3239 /*
3240 * If external control is enabled then initiate
3241 * TDLS only if forced peer is set otherwise
3242 * ignore should Discover trigger from fw.
3243 */
3244 if (pHddCtx->config->
3245 fTDLSExternalControl
3246 && (false ==
3247 curr_peer->isForcedPeer)) {
3248 hddLog(LOG2,
3249 FL
3250 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303251 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003252 break;
3253 } else {
3254 hddLog(LOG2,
3255 FL
3256 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3257 pHddCtx->config->
3258 fTDLSExternalControl,
3259 curr_peer->isForcedPeer,
3260 pRoamInfo->reasonCode);
3261 }
3262 wlan_hdd_tdls_pre_setup_init_work
3263 (pHddTdlsCtx, curr_peer);
3264 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303265 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003266 }
3267 break;
3268 }
3269
3270 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3271 {
3272 curr_peer =
3273 wlan_hdd_tdls_find_peer(pAdapter,
3274 pRoamInfo->peerMac.bytes, true);
3275 if (!curr_peer) {
3276 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303277 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003278 } else {
3279 if (eTDLS_LINK_CONNECTED ==
3280 curr_peer->link_status) {
3281 hddLog(LOGE,
3282 FL
3283 ("Received SHOULD_TEARDOWN for peer "
3284 MAC_ADDRESS_STR
3285 " staId: %d, reason: %d"),
3286 MAC_ADDR_ARRAY(pRoamInfo->
3287 peerMac.bytes),
3288 pRoamInfo->staId,
3289 pRoamInfo->reasonCode);
3290
3291 if (pRoamInfo->reasonCode ==
3292 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3293 pRoamInfo->reasonCode ==
3294 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3295 pRoamInfo->reasonCode ==
3296 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3297 pRoamInfo->reasonCode ==
3298 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3299 reason =
3300 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3301 } else
3302 reason =
3303 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3304
3305 wlan_hdd_tdls_indicate_teardown
3306 (pHddTdlsCtx->pAdapter, curr_peer,
3307 reason);
3308 } else {
3309 hddLog(LOGE,
3310 FL
3311 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3312 pRoamInfo->reasonCode);
3313 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303314 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003315 }
3316 break;
3317 }
3318
3319 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3320 {
3321 curr_peer =
3322 wlan_hdd_tdls_find_peer(pAdapter,
3323 pRoamInfo->peerMac.bytes, true);
3324 if (!curr_peer) {
3325 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303326 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003327 } else {
3328 if (eTDLS_LINK_CONNECTED ==
3329 curr_peer->link_status) {
3330 hddLog(LOGE,
3331 FL
3332 ("Received SHOULD_PEER_DISCONNECTED for peer "
3333 MAC_ADDRESS_STR
3334 " staId: %d, reason: %d"),
3335 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3336 pRoamInfo->staId,
3337 pRoamInfo->reasonCode);
3338
3339 if (pRoamInfo->reasonCode ==
3340 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3341 pRoamInfo->reasonCode ==
3342 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3343 pRoamInfo->reasonCode ==
3344 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3345 pRoamInfo->reasonCode ==
3346 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3347 reason =
3348 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3349 } else
3350 reason =
3351 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3352
3353 wlan_hdd_tdls_indicate_teardown
3354 (pHddTdlsCtx->pAdapter, curr_peer,
3355 reason);
3356 } else {
3357 hddLog(LOGE,
3358 FL
3359 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3360 pRoamInfo->reasonCode);
3361 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303362 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003363 }
3364 break;
3365 }
3366 default:
3367 {
3368 break;
3369 }
3370 }
3371
3372 return status;
3373}
3374#endif
3375
3376#ifdef WLAN_FEATURE_11W
3377/**
3378 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3379 * @pAdapter: pointer to the adapter
3380 * @nFrameLength: Length of the unprotected frame being passed
3381 * @pbFrames: Pointer to the frame buffer
3382 * @frameType: 802.11 frame type
3383 *
3384 * This function forwards the unprotected management frame to the supplicant.
3385 *
3386 * Return: nothing
3387 */
3388static void
3389hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3390 uint8_t *pbFrames, uint8_t frameType)
3391{
3392 uint8_t type = 0;
3393 uint8_t subType = 0;
3394
3395 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3396 frameType, nFrameLength);
3397
3398 /* Sanity Checks */
3399 if (NULL == pAdapter) {
3400 hddLog(LOGE, FL("pAdapter is NULL"));
3401 return;
3402 }
3403
3404 if (NULL == pAdapter->dev) {
3405 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3406 return;
3407 }
3408
3409 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3410 hddLog(LOGE, FL("pAdapter has invalid magic"));
3411 return;
3412 }
3413
3414 if (!nFrameLength) {
3415 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3416 return;
3417 }
3418
3419 if (NULL == pbFrames) {
3420 hddLog(LOGE, FL("pbFrames is NULL"));
3421 return;
3422 }
3423
3424 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3425 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3426
3427 /* Get pAdapter from Destination mac address of the frame */
3428 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3429#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3430 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3431 nFrameLength);
3432#else
3433 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3434 nFrameLength);
3435#endif
3436 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3437 } else if (type == SIR_MAC_MGMT_FRAME &&
3438 subType == SIR_MAC_MGMT_DEAUTH) {
3439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3440 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3441 nFrameLength);
3442#else
3443 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3444 nFrameLength);
3445#endif
3446 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3447 } else {
3448 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3449 type, subType);
3450 return;
3451 }
3452}
3453#endif
3454
3455#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
3456/**
3457 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3458 * @pAdapter: pointer to adapter
3459 * @tid: traffic identifier
3460 * @state: state
3461 * @measInterval: measurement interval
3462 *
3463 * This function sends traffic stream metrics IE information to
3464 * the supplicant via wireless event.
3465 *
3466 * Return: none
3467 */
3468static void
3469hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3470 uint8_t state, uint16_t measInterval)
3471{
3472 union iwreq_data wrqu;
3473 char buf[IW_CUSTOM_MAX + 1];
3474 int nBytes = 0;
3475
3476 if (NULL == pAdapter)
3477 return;
3478
3479 /* create the event */
3480 memset(&wrqu, '\0', sizeof(wrqu));
3481 memset(buf, '\0', sizeof(buf));
3482
3483 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3484 tid, state, measInterval);
3485
3486 nBytes =
3487 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3488 measInterval);
3489
3490 wrqu.data.pointer = buf;
3491 wrqu.data.length = nBytes;
3492 /* send the event */
3493 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3494}
3495
3496/**
3497 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3498 * @pAdapter: pointer to adapter
3499 * @pRoamInfo: pointer to roam info
3500 *
3501 * This function sends cckm preauth indication to the supplicant
3502 * via wireless custom event.
3503 *
3504 * Return: none
3505 */
3506static void
3507hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3508{
3509 union iwreq_data wrqu;
3510 char buf[IW_CUSTOM_MAX + 1];
3511 char *pos = buf;
3512 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3513
3514 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3515 return;
3516
3517 /* create the event */
3518 memset(&wrqu, '\0', sizeof(wrqu));
3519 memset(buf, '\0', sizeof(buf));
3520
3521 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3522 hddLog(LOG1,
3523 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3524 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3525 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3526
3527 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3528 pos += nBytes;
3529 freeBytes -= nBytes;
3530
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303531 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303532 pos += QDF_MAC_ADDR_SIZE;
3533 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003534
3535 nBytes = snprintf(pos, freeBytes, " %u:%u",
3536 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3537 freeBytes -= nBytes;
3538
3539 wrqu.data.pointer = buf;
3540 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3541
3542 /* send the event */
3543 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3544}
3545
3546/**
3547 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3548 * @pAdapter: pointer to adapter
3549 * @pRoamInfo: pointer to roam info
3550 *
3551 * Return: none
3552 */
3553static void
3554hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3555 tCsrRoamInfo *pRoamInfo)
3556{
3557 union iwreq_data wrqu;
3558 char buf[IW_CUSTOM_MAX + 1];
3559 int nBytes = 0;
3560
3561 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3562 return;
3563
3564 /* create the event */
3565 memset(&wrqu, '\0', sizeof(wrqu));
3566 memset(buf, '\0', sizeof(buf));
3567
3568 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3569
3570 nBytes =
3571 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3572 pRoamInfo->tsmRoamDelay);
3573
3574 wrqu.data.pointer = buf;
3575 wrqu.data.length = nBytes;
3576
3577 /* send the event */
3578 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3579}
3580
3581/**
3582 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3583 * @pAdapter: pointer to adapter
3584 * @measurementToken: measurement token
3585 * @flag: flag
3586 * @numBss: number of bss
3587 *
3588 * If the measurement is none and no scan results found,
3589 * indicate the supplicant about measurement done.
3590 *
3591 * Return: none
3592 */
3593void
3594hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3595 const uint16_t measurementToken,
3596 const bool flag, const uint8_t numBss)
3597{
3598 union iwreq_data wrqu;
3599 char buf[IW_CUSTOM_MAX];
3600 char *pos = buf;
3601 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3602
3603 memset(&wrqu, '\0', sizeof(wrqu));
3604 memset(buf, '\0', sizeof(buf));
3605
3606 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3607 flag, numBss);
3608
3609 nBytes =
3610 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3611 flag, numBss);
3612
3613 wrqu.data.pointer = buf;
3614 wrqu.data.length = nBytes;
3615 /* send the event */
3616 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3617}
3618
3619/**
3620 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3621 * @pAdapter: pointer to adapter
3622 * @pRoamInfo: pointer to roam info
3623 *
3624 * If the measurement is none and no scan results found,
3625 * indicate the supplicant about measurement done.
3626 *
3627 * Return: none
3628 */
3629static void
3630hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3631 const tCsrRoamInfo *pRoamInfo)
3632{
3633 union iwreq_data wrqu;
3634 char buf[IW_CUSTOM_MAX];
3635 char *pos = buf;
3636 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3637 uint8_t i = 0, len = 0;
3638 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3639 uint8_t lastSent = 0, sendBss = 0;
3640 int bcnRepFieldSize =
3641 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3642 bcnReportFields);
3643 uint8_t ieLenByte = 1;
3644 /*
3645 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3646 */
3647#define ESEBCNREPHEADER_LEN (18)
3648
3649 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3650 return;
3651
3652 /*
3653 * Custom event can pass maximum of 256 bytes of data,
3654 * based on the IE len we need to identify how many BSS info can
3655 * be filled in to custom event data.
3656 */
3657 /*
3658 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3659 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3660 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3661 */
3662
3663 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3664 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3665 hddLog(LOG1,
3666 "Measurement Done but no scan results");
3667 /* If the measurement is none and no scan results found,
3668 indicate the supplicant about measurement done */
3669 hdd_indicate_ese_bcn_report_no_results(
3670 pAdapter,
3671 pRoamInfo->pEseBcnReportRsp->
3672 measurementToken,
3673 pRoamInfo->pEseBcnReportRsp->flag,
3674 pRoamInfo->pEseBcnReportRsp->numBss);
3675 } else {
3676 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3677 memset(&wrqu, '\0', sizeof(wrqu));
3678 memset(buf, '\0', sizeof(buf));
3679 tot_bcn_ieLen = 0;
3680 sendBss = 0;
3681 pos = buf;
3682 freeBytes = IW_CUSTOM_MAX;
3683
3684 for (i = lastSent;
3685 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3686 len =
3687 bcnRepFieldSize + ieLenByte +
3688 pRoamInfo->pEseBcnReportRsp->
3689 bcnRepBssInfo[i].ieLen;
3690 if ((len + tot_bcn_ieLen) >
3691 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3692 break;
3693 }
3694 tot_bcn_ieLen += len;
3695 sendBss++;
3696 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3697 i, bcnRepFieldSize, 1,
3698 pRoamInfo->pEseBcnReportRsp->
3699 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3700 }
3701
3702 hddLog(LOG1, "Sending %d BSS Info",
3703 sendBss);
3704 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3705 pRoamInfo->pEseBcnReportRsp->measurementToken,
3706 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3707 tot_bcn_ieLen);
3708
3709 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3710 pRoamInfo->pEseBcnReportRsp->
3711 measurementToken,
3712 pRoamInfo->pEseBcnReportRsp->flag,
3713 sendBss);
3714 pos += nBytes;
3715 freeBytes -= nBytes;
3716
3717 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303718 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003719 sizeof(tot_bcn_ieLen));
3720 pos += sizeof(tot_bcn_ieLen);
3721 freeBytes -= sizeof(tot_bcn_ieLen);
3722
3723 for (i = 0; i < sendBss; i++) {
3724 hddLog(LOG1,
3725 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3726 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3727 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3728 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3729 pRoamInfo->pEseBcnReportRsp->
3730 bcnRepBssInfo[i +
3731 lastSent].bcnReportFields.
3732 ChanNum,
3733 pRoamInfo->pEseBcnReportRsp->
3734 bcnRepBssInfo[i +
3735 lastSent].bcnReportFields.
3736 Spare,
3737 pRoamInfo->pEseBcnReportRsp->
3738 bcnRepBssInfo[i +
3739 lastSent].bcnReportFields.
3740 MeasDuration,
3741 pRoamInfo->pEseBcnReportRsp->
3742 bcnRepBssInfo[i +
3743 lastSent].bcnReportFields.
3744 PhyType,
3745 pRoamInfo->pEseBcnReportRsp->
3746 bcnRepBssInfo[i +
3747 lastSent].bcnReportFields.
3748 RecvSigPower,
3749 pRoamInfo->pEseBcnReportRsp->
3750 bcnRepBssInfo[i +
3751 lastSent].bcnReportFields.
3752 ParentTsf,
3753 pRoamInfo->pEseBcnReportRsp->
3754 bcnRepBssInfo[i +
3755 lastSent].bcnReportFields.
3756 TargetTsf[0],
3757 pRoamInfo->pEseBcnReportRsp->
3758 bcnRepBssInfo[i +
3759 lastSent].bcnReportFields.
3760 TargetTsf[1],
3761 pRoamInfo->pEseBcnReportRsp->
3762 bcnRepBssInfo[i +
3763 lastSent].bcnReportFields.
3764 BcnInterval,
3765 pRoamInfo->pEseBcnReportRsp->
3766 bcnRepBssInfo[i +
3767 lastSent].bcnReportFields.
3768 CapabilityInfo,
3769 pRoamInfo->pEseBcnReportRsp->
3770 bcnRepBssInfo[i +
3771 lastSent].bcnReportFields.
3772 Bssid[0],
3773 pRoamInfo->pEseBcnReportRsp->
3774 bcnRepBssInfo[i +
3775 lastSent].bcnReportFields.
3776 Bssid[1],
3777 pRoamInfo->pEseBcnReportRsp->
3778 bcnRepBssInfo[i +
3779 lastSent].bcnReportFields.
3780 Bssid[2],
3781 pRoamInfo->pEseBcnReportRsp->
3782 bcnRepBssInfo[i +
3783 lastSent].bcnReportFields.
3784 Bssid[3],
3785 pRoamInfo->pEseBcnReportRsp->
3786 bcnRepBssInfo[i +
3787 lastSent].bcnReportFields.
3788 Bssid[4],
3789 pRoamInfo->pEseBcnReportRsp->
3790 bcnRepBssInfo[i +
3791 lastSent].bcnReportFields.
3792 Bssid[5]);
3793
3794 /* bcn report fields are copied */
3795 len =
3796 sizeof(pRoamInfo->pEseBcnReportRsp->
3797 bcnRepBssInfo[i +
3798 lastSent].
3799 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303800 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003801 (char *)&pRoamInfo->
3802 pEseBcnReportRsp->bcnRepBssInfo[i +
3803 lastSent].
3804 bcnReportFields, len);
3805 pos += len;
3806 freeBytes -= len;
3807
3808 /* Add 1 byte of ie len */
3809 len =
3810 pRoamInfo->pEseBcnReportRsp->
3811 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303812 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003813 pos += sizeof(len);
3814 freeBytes -= sizeof(len);
3815
3816 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303817 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003818 (char *)pRoamInfo->
3819 pEseBcnReportRsp->bcnRepBssInfo[i +
3820 lastSent].
3821 pBuf, len);
3822 pos += len;
3823 freeBytes -= len;
3824 }
3825
3826 wrqu.data.pointer = buf;
3827 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3828
3829 /* send the event */
3830 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3831 buf);
3832 lastSent += sendBss;
3833 }
3834 }
3835}
3836
3837#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
3838
3839/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303840 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
3841 * @pHddStaCtx: Station Context
3842 *
3843 * API to check if the connection authentication type is 8021x_sha256.
3844 *
3845 * Return: bool
3846 */
3847#ifdef WLAN_FEATURE_11W
3848static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3849{
3850 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
3851 pHddStaCtx->conn_info.authType;
3852}
3853#else
3854static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3855{
3856 return false;
3857}
3858#endif
3859
3860/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003861 * hdd_sme_roam_callback() - hdd sme roam callback
3862 * @pContext: pointer to adapter context
3863 * @pRoamInfo: pointer to roam info
3864 * @roamId: roam id
3865 * @roamStatus: roam status
3866 * @roamResult: roam result
3867 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303868 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003869 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303870QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003871hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3872 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3873{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303874 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003875 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3876 hdd_wext_state_t *pWextState = NULL;
3877 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303878 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003879 hdd_context_t *pHddCtx = NULL;
3880
3881 hddLog(LOG2,
3882 "CSR Callback: status= %d result= %d roamID=%d",
3883 roamStatus, roamResult, roamId);
3884
3885 /* Sanity check */
3886 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3887 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303888 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003889 }
3890
3891 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3892 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3893
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303894 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05303895 pAdapter->sessionId, roamStatus));
3896
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003897 switch (roamStatus) {
3898 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05303899 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3900 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08003901 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003902 break;
3903
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003904 /*
3905 * We did pre-auth,then we attempted a 11r or ese reassoc.
3906 * reassoc failed due to failure, timeout, reject from ap
3907 * in any case tell the OS, our carrier is off and mark
3908 * interface down.
3909 */
3910 case eCSR_ROAM_FT_REASSOC_FAILED:
3911 hddLog(LOGE,
3912 FL
3913 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
3914 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303915 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003916 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3917 roamStatus, roamResult);
3918 /*
3919 * Check if Mcast/Bcast Filters are set, if yes
3920 * clear the filters here.
3921 */
3922 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
3923 true) {
3924 (WLAN_HDD_GET_CTX(pAdapter))->
3925 hdd_mcastbcast_filter_set = false;
3926 }
3927 pHddStaCtx->ft_carrier_on = false;
3928 pHddStaCtx->hdd_ReassocScenario = false;
3929 hddLog(LOG1,
3930 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
3931 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3932 break;
3933
3934 case eCSR_ROAM_FT_START:
3935 /*
3936 * When we roam for ESE and 11r, we dont want the OS to be
3937 * informed that the link is down. So mark the link ready for
3938 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
3939 * be received. Where in we will not mark the link down
3940 * Also we want to stop tx at this point when we will be
3941 * doing disassoc at this time. This saves 30-60 msec
3942 * after reassoc.
3943 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003944 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07003945 wlan_hdd_netif_queue_control(pAdapter,
3946 WLAN_NETIF_TX_DISABLE,
3947 WLAN_CONTROL_PATH);
3948 status = hdd_roam_deregister_sta(pAdapter,
3949 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303950 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303951 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003952 pHddStaCtx->ft_carrier_on = true;
3953 pHddStaCtx->hdd_ReassocScenario = true;
3954 hddLog(LOG1,
3955 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
3956 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3957 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003958
3959 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003960 /* notify apps that we can't pass traffic anymore */
3961 hddLog(LOG1, FL("Disabling queues"));
3962 wlan_hdd_netif_queue_control(pAdapter,
3963 WLAN_NETIF_TX_DISABLE,
3964 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003965 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003966 wlan_hdd_netif_queue_control(pAdapter,
3967 WLAN_NETIF_CARRIER_OFF,
3968 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003969 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003970 break;
3971 case eCSR_ROAM_LOSTLINK:
3972 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
3973 hddLog(LOG2, "Roaming started due to connection lost");
3974 hddLog(LOG1, FL("Disabling queues"));
3975 wlan_hdd_netif_queue_control(pAdapter,
3976 WLAN_NETIF_TX_DISABLE_N_CARRIER,
3977 WLAN_CONTROL_PATH);
3978 break;
3979 }
3980 case eCSR_ROAM_DISASSOCIATED:
3981 {
3982 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303983 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003984 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3985 roamStatus, roamResult);
3986 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
3987 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3988 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
3989 hdd_conf_mcastbcast_filter(pHddCtx, false);
3990
3991 if (true ==
3992 pHddCtx->sus_res_mcastbcast_filter_valid) {
3993 pHddCtx->configuredMcastBcastFilter =
3994 pHddCtx->sus_res_mcastbcast_filter;
3995 pHddCtx->
3996 sus_res_mcastbcast_filter_valid =
3997 false;
3998 }
3999
4000 hddLog(LOG1,
4001 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4002 hddLog(LOG1,
4003 "McastBcastFilter = %d",
4004 pHddCtx->configuredMcastBcastFilter);
4005 hddLog(LOG1,
4006 "offload: already called mcastbcast filter");
4007 (WLAN_HDD_GET_CTX(pAdapter))->
4008 hdd_mcastbcast_filter_set = false;
4009 }
4010 /* Call to clear any MC Addr List filter applied after
4011 * successful connection.
4012 */
4013 wlan_hdd_set_mc_addr_list(pAdapter, false);
4014 }
4015 break;
4016 case eCSR_ROAM_IBSS_LEAVE:
4017 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304018 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004019 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4020 roamStatus, roamResult);
4021 break;
4022 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4023 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4024 /*
4025 * To Do - address probable memory leak with WEP encryption upon
4026 * successful association.
4027 */
4028 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4029 /* Clear saved connection information in HDD */
4030 hdd_conn_remove_connect_info(
4031 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4032 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304033 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004034 hdd_association_completion_handler(pAdapter, pRoamInfo,
4035 roamId, roamStatus,
4036 roamResult);
4037#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4038 if (pRoamInfo)
4039 pRoamInfo->roamSynchInProgress = false;
4040#endif
4041 break;
4042 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304043 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004044 pRoamInfo,
4045 roamId,
4046 roamStatus,
4047 roamResult);
4048 break;
4049 case eCSR_ROAM_IBSS_IND:
4050 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4051 roamStatus, roamResult);
4052 break;
4053
4054 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304055 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004056 roam_roam_connect_status_update_handler(pAdapter,
4057 pRoamInfo,
4058 roamId,
4059 roamStatus,
4060 roamResult);
4061 break;
4062
4063 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304064 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004065 hdd_roam_mic_error_indication_handler(pAdapter,
4066 pRoamInfo,
4067 roamId,
4068 roamStatus,
4069 roamResult);
4070 break;
4071
4072 case eCSR_ROAM_SET_KEY_COMPLETE:
4073 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304074 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004075 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4076 roamId, roamStatus,
4077 roamResult);
4078 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4079 pHddStaCtx->hdd_ReassocScenario = false;
4080 hddLog(LOG1,
4081 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4082 pHddStaCtx->hdd_ReassocScenario,
4083 pAdapter->sessionId);
4084 }
4085 }
4086#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4087 if (pRoamInfo != NULL)
4088 pRoamInfo->roamSynchInProgress = false;
4089#endif
4090 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004091
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004092 case eCSR_ROAM_FT_RESPONSE:
4093 hdd_send_ft_event(pAdapter);
4094 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004095
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004096 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304097 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4098 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004099 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304100 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004101 wlan_hdd_cfg80211_pmksa_candidate_notify(
4102 pAdapter, pRoamInfo, 1, false);
4103 }
4104 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004105
4106#ifdef FEATURE_WLAN_LFR_METRICS
4107 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4108 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304109 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004110 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4111 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304112 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004113 }
4114 break;
4115 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4116 /*
4117 * This event will notify pre-auth completion in case of success
4118 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304119 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004120 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4121 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304122 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004123 }
4124 break;
4125 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4126 /*
4127 * This event will notify pre-auth completion incase of failure.
4128 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304129 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004130 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4131 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304132 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004133 }
4134 break;
4135 case eCSR_ROAM_HANDOVER_SUCCESS:
4136 /* This event is to notify handover success.
4137 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304138 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004139 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4140 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304141 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004142 }
4143 break;
4144#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004145 case eCSR_ROAM_REMAIN_CHAN_READY:
4146 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4147 break;
4148 case eCSR_ROAM_SEND_ACTION_CNF:
4149 hdd_send_action_cnf(pAdapter,
4150 (roamResult ==
4151 eCSR_ROAM_RESULT_NONE) ? true : false);
4152 break;
4153#ifdef FEATURE_WLAN_TDLS
4154 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304155 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004156 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4157 roamId,
4158 roamStatus,
4159 roamResult);
4160 break;
4161 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4162 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4163 pRoamInfo->reasonCode);
4164 break;
4165#endif
4166#ifdef WLAN_FEATURE_11W
4167 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4168 hdd_indicate_unprot_mgmt_frame(pAdapter,
4169 pRoamInfo->nFrameLength,
4170 pRoamInfo->pbFrames,
4171 pRoamInfo->frameType);
4172 break;
4173#endif
4174#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4175 case eCSR_ROAM_TSM_IE_IND:
4176 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4177 pRoamInfo->tsmIe.state,
4178 pRoamInfo->tsmIe.msmt_interval);
4179 break;
4180
4181 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4182 {
4183 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4184 pHddStaCtx->conn_info.authType
4185 || eCSR_AUTH_TYPE_CCKM_RSN ==
4186 pHddStaCtx->conn_info.authType) {
4187 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4188 }
4189 break;
4190 }
4191
4192 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4193 {
4194 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4195 break;
4196 }
4197
4198 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4199 {
4200 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4201 break;
4202 }
4203#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
4204 default:
4205 break;
4206 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304207 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004208}
4209
4210/**
4211 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4212 * @auth_suite: auth suite
4213 *
4214 * Return: eCsrAuthType enumeration
4215 */
4216eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4217{
4218 eCsrAuthType auth_type;
4219 /* is the auth type supported? */
4220 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4221 auth_type = eCSR_AUTH_TYPE_RSN;
4222 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4223 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004224 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004225 /* Check for 11r FT Authentication with PSK */
4226 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4227 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4228 /* Check for 11R FT Authentication with 802.1X */
4229 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4230 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004231#ifdef FEATURE_WLAN_ESE
4232 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4233 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4234 } else
4235#endif /* FEATURE_WLAN_ESE */
4236#ifdef WLAN_FEATURE_11W
4237 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4238 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4239 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4240 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4241 } else
4242#endif
4243 {
4244 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4245 }
4246 return auth_type;
4247}
4248
4249/**
4250 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4251 * @auth_suite: auth suite
4252 *
4253 * Return: eCsrAuthType enumeration
4254 */
4255eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4256{
4257 eCsrAuthType auth_type;
4258 /* is the auth type supported? */
4259 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4260 auth_type = eCSR_AUTH_TYPE_WPA;
4261 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4262 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4263 } else
4264#ifdef FEATURE_WLAN_ESE
4265 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4266 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4267 } else
4268#endif /* FEATURE_WLAN_ESE */
4269 {
4270 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4271 }
4272 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4273 return auth_type;
4274}
4275
4276/**
4277 * hdd_translate_rsn_to_csr_encryption_type() -
4278 * Translate RSN to CSR encryption type
4279 * @cipher_suite: cipher suite
4280 *
4281 * Return: eCsrEncryptionType enumeration
4282 */
4283eCsrEncryptionType
4284hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4285{
4286 eCsrEncryptionType cipher_type;
4287
4288 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4289 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4290 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4291 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4292 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4293 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4294 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4295 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4296 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4297 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4298 else
4299 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4300
4301 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4302 return cipher_type;
4303}
4304
4305/**
4306 * hdd_translate_wpa_to_csr_encryption_type() -
4307 * Translate WPA to CSR encryption type
4308 * @cipher_suite: cipher suite
4309 *
4310 * Return: eCsrEncryptionType enumeration
4311 */
4312eCsrEncryptionType
4313hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4314{
4315 eCsrEncryptionType cipher_type;
4316
4317 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4318 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4319 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4320 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4321 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4322 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4323 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4324 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4325 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4326 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4327 else
4328 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4329
4330 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4331 return cipher_type;
4332}
4333
4334/**
4335 * hdd_process_genie() - process gen ie
4336 * @pAdapter: pointer to adapter
4337 * @bssid: pointer to mac address
4338 * @pEncryptType: pointer to encryption type
4339 * @mcEncryptType: pointer to multicast encryption type
4340 * @pAuthType: pointer to auth type
4341 *
4342 * Return: 0 on success, error number otherwise
4343 */
4344static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4345 u8 *bssid,
4346 eCsrEncryptionType *pEncryptType,
4347 eCsrEncryptionType *mcEncryptType,
4348 eCsrAuthType *pAuthType,
4349#ifdef WLAN_FEATURE_11W
4350 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4351#endif
4352 uint16_t gen_ie_len, uint8_t *gen_ie)
4353{
4354 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304355 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004356 tDot11fIERSN dot11RSNIE;
4357 tDot11fIEWPA dot11WPAIE;
4358 uint32_t i;
4359 uint8_t *pRsnIe;
4360 uint16_t RSNIeLen;
4361 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4362 bool updatePMKCache = false;
4363
4364 /*
4365 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4366 * setting present flag to 0.
4367 */
4368 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4369 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4370
4371 /* Type check */
4372 if (gen_ie[0] == DOT11F_EID_RSN) {
4373 /* Validity checks */
4374 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4375 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4376 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4377 gen_ie_len);
4378 return -EINVAL;
4379 }
4380 /* Skip past the EID byte and length byte */
4381 pRsnIe = gen_ie + 2;
4382 RSNIeLen = gen_ie_len - 2;
4383 /* Unpack the RSN IE */
4384 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4385 pRsnIe, RSNIeLen, &dot11RSNIE);
4386 /* Copy out the encryption and authentication types */
4387 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4388 dot11RSNIE.pwise_cipher_suite_count);
4389 hddLog(LOG1, FL("authentication suite count: %d"),
4390 dot11RSNIE.akm_suite_count);
4391 /*Here we have followed the apple base code,
4392 but probably I suspect we can do something different */
4393 /* dot11RSNIE.akm_suite_count */
4394 /* Just translate the FIRST one */
4395 *pAuthType =
4396 hdd_translate_rsn_to_csr_auth_type(
4397 dot11RSNIE.akm_suites[0]);
4398 /* dot11RSNIE.pwise_cipher_suite_count */
4399 *pEncryptType =
4400 hdd_translate_rsn_to_csr_encryption_type(
4401 dot11RSNIE.pwise_cipher_suites[0]);
4402 /* dot11RSNIE.gp_cipher_suite_count */
4403 *mcEncryptType =
4404 hdd_translate_rsn_to_csr_encryption_type(
4405 dot11RSNIE.gp_cipher_suite);
4406#ifdef WLAN_FEATURE_11W
4407 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4408 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4409#endif
4410 /* Set the PMKSA ID Cache for this interface */
4411 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4412 if (is_zero_ether_addr(bssid)) {
4413 hddLog(LOGE, FL("MAC address is all zeroes"));
4414 break;
4415 }
4416 updatePMKCache = true;
4417 /*
4418 * For right now, I assume setASSOCIATE() has passed
4419 * in the bssid.
4420 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304421 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304422 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304423 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004424 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4425 }
4426
4427 if (updatePMKCache) {
4428 /*
4429 * Calling csr_roam_set_pmkid_cache to configure the
4430 * PMKIDs into the cache.
4431 */
4432 hddLog(LOG1,
4433 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4434 i);
4435 /* Finally set the PMKSA ID Cache in CSR */
4436 result =
4437 sme_roam_set_pmkid_cache(halHandle,
4438 pAdapter->sessionId,
4439 PMKIDCache,
4440 dot11RSNIE.pmkid_count,
4441 false);
4442 }
4443 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4444 /* Validity checks */
4445 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4446 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4447 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4448 gen_ie_len);
4449 return -EINVAL;
4450 }
4451 /* Skip past the EID and length byte - and four byte WiFi OUI */
4452 pRsnIe = gen_ie + 2 + 4;
4453 RSNIeLen = gen_ie_len - (2 + 4);
4454 /* Unpack the WPA IE */
4455 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4456 pRsnIe, RSNIeLen, &dot11WPAIE);
4457 /* Copy out the encryption and authentication types */
4458 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4459 dot11WPAIE.unicast_cipher_count);
4460 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4461 dot11WPAIE.auth_suite_count);
4462 /* dot11WPAIE.auth_suite_count */
4463 /* Just translate the FIRST one */
4464 *pAuthType =
4465 hdd_translate_wpa_to_csr_auth_type(
4466 dot11WPAIE.auth_suites[0]);
4467 /* dot11WPAIE.unicast_cipher_count */
4468 *pEncryptType =
4469 hdd_translate_wpa_to_csr_encryption_type(
4470 dot11WPAIE.unicast_ciphers[0]);
4471 /* dot11WPAIE.unicast_cipher_count */
4472 *mcEncryptType =
4473 hdd_translate_wpa_to_csr_encryption_type(
4474 dot11WPAIE.multicast_cipher);
4475 } else {
4476 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4477 return -EINVAL;
4478 }
4479 return 0;
4480}
4481
4482/**
4483 * hdd_set_genie_to_csr() - set genie to csr
4484 * @pAdapter: pointer to adapter
4485 * @RSNAuthType: pointer to auth type
4486 *
4487 * Return: 0 on success, error number otherwise
4488 */
4489int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4490{
4491 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4492 uint32_t status = 0;
4493 eCsrEncryptionType RSNEncryptType;
4494 eCsrEncryptionType mcRSNEncryptType;
4495#ifdef WLAN_FEATURE_11W
4496 uint8_t RSNMfpRequired = 0;
4497 uint8_t RSNMfpCapable = 0;
4498#endif
4499 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4500 /* MAC address of assoc peer */
4501 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304502 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004503 pWextState->roamProfile.BSSIDs.bssid,
4504 sizeof(bssid));
4505 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4506 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4507 /* continue */
4508 } else {
4509 return 0;
4510 }
4511 /* The actual processing may eventually be more extensive than this. */
4512 /* Right now, just consume any PMKIDs that are sent in by the app. */
4513 status = hdd_process_genie(pAdapter, bssid,
4514 &RSNEncryptType,
4515 &mcRSNEncryptType, RSNAuthType,
4516#ifdef WLAN_FEATURE_11W
4517 &RSNMfpRequired, &RSNMfpCapable,
4518#endif
4519 pWextState->WPARSNIE[1] + 2,
4520 pWextState->WPARSNIE);
4521 if (status == 0) {
4522 /*
4523 * Now copy over all the security attributes
4524 * you have parsed out.
4525 */
4526 pWextState->roamProfile.EncryptionType.numEntries = 1;
4527 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4528
4529 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4530 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4531 mcRSNEncryptType;
4532
4533 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
4534 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4535 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4536 /*
4537 * For wpa none supplicant sends the WPA IE with unicast
4538 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4539 * multicast cipher as either AES/TKIP based on group
4540 * cipher configuration mentioned in the
4541 * wpa_supplicant.conf.
4542 */
4543
4544 /* Set the unicast cipher same as multicast cipher */
4545 pWextState->roamProfile.EncryptionType.encryptionType[0]
4546 = mcRSNEncryptType;
4547 }
4548#ifdef WLAN_FEATURE_11W
4549 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4550 RSNMfpRequired, RSNMfpCapable);
4551 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4552 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4553#endif
4554 hddLog(LOG1,
4555 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4556 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4557 }
4558 return 0;
4559}
4560
4561/**
4562 * hdd_set_csr_auth_type() - set csr auth type
4563 * @pAdapter: pointer to adapter
4564 * @RSNAuthType: auth type
4565 *
4566 * Return: 0 on success, error number otherwise
4567 */
4568int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4569{
4570 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4571 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4572 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4573 ENTER();
4574
4575 pRoamProfile->AuthType.numEntries = 1;
4576 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4577 pHddStaCtx->conn_info.authType);
4578
4579 switch (pHddStaCtx->conn_info.authType) {
4580 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4581#ifdef FEATURE_WLAN_ESE
4582 case eCSR_AUTH_TYPE_CCKM_WPA:
4583 case eCSR_AUTH_TYPE_CCKM_RSN:
4584#endif
4585 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4586
4587 pRoamProfile->AuthType.authType[0] =
4588 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4589 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4590
4591#ifdef FEATURE_WLAN_ESE
4592 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4593 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4594 == IW_AUTH_KEY_MGMT_802_1X)) {
4595 hddLog(LOG1,
4596 FL("set authType to CCKM WPA. AKM also 802.1X."));
4597 pRoamProfile->AuthType.authType[0] =
4598 eCSR_AUTH_TYPE_CCKM_WPA;
4599 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4600 hddLog(LOG1,
4601 FL("Last chance to set authType to CCKM WPA."));
4602 pRoamProfile->AuthType.authType[0] =
4603 eCSR_AUTH_TYPE_CCKM_WPA;
4604 } else
4605#endif
4606 if ((pWextState->
4607 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4608 == IW_AUTH_KEY_MGMT_802_1X) {
4609 pRoamProfile->AuthType.authType[0] =
4610 eCSR_AUTH_TYPE_WPA;
4611 } else
4612 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4613 == IW_AUTH_KEY_MGMT_PSK) {
4614 pRoamProfile->AuthType.authType[0] =
4615 eCSR_AUTH_TYPE_WPA_PSK;
4616 } else {
4617 pRoamProfile->AuthType.authType[0] =
4618 eCSR_AUTH_TYPE_WPA_NONE;
4619 }
4620 }
4621 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4622#ifdef FEATURE_WLAN_ESE
4623 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4624 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4625 == IW_AUTH_KEY_MGMT_802_1X)) {
4626 hddLog(LOG1,
4627 FL("set authType to CCKM RSN. AKM also 802.1X."));
4628 pRoamProfile->AuthType.authType[0] =
4629 eCSR_AUTH_TYPE_CCKM_RSN;
4630 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4631 hddLog(LOG1,
4632 FL("Last chance to set authType to CCKM RSN."));
4633 pRoamProfile->AuthType.authType[0] =
4634 eCSR_AUTH_TYPE_CCKM_RSN;
4635 } else
4636#endif
4637
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004638 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4639 ((pWextState->
4640 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4641 == IW_AUTH_KEY_MGMT_802_1X)) {
4642 pRoamProfile->AuthType.authType[0] =
4643 eCSR_AUTH_TYPE_FT_RSN;
4644 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4645 &&
4646 ((pWextState->
4647 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4648 == IW_AUTH_KEY_MGMT_PSK)) {
4649 pRoamProfile->AuthType.authType[0] =
4650 eCSR_AUTH_TYPE_FT_RSN_PSK;
4651 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004652
4653#ifdef WLAN_FEATURE_11W
4654 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4655 pRoamProfile->AuthType.authType[0] =
4656 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4657 } else if (RSNAuthType ==
4658 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4659 pRoamProfile->AuthType.authType[0] =
4660 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4661 } else
4662#endif
4663
4664 if ((pWextState->
4665 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4666 == IW_AUTH_KEY_MGMT_802_1X) {
4667 pRoamProfile->AuthType.authType[0] =
4668 eCSR_AUTH_TYPE_RSN;
4669 } else
4670 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4671 == IW_AUTH_KEY_MGMT_PSK) {
4672 pRoamProfile->AuthType.authType[0] =
4673 eCSR_AUTH_TYPE_RSN_PSK;
4674 } else {
4675 pRoamProfile->AuthType.authType[0] =
4676 eCSR_AUTH_TYPE_UNKNOWN;
4677 }
4678 }
4679 break;
4680
4681 case eCSR_AUTH_TYPE_SHARED_KEY:
4682
4683 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4684 break;
4685 default:
4686
4687#ifdef FEATURE_WLAN_ESE
4688 hddLog(LOG1, FL("In default, unknown auth type."));
4689#endif /* FEATURE_WLAN_ESE */
4690 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4691 break;
4692 }
4693
4694 hddLog(LOG1, FL("Set roam Authtype to %d"),
4695 pWextState->roamProfile.AuthType.authType[0]);
4696
4697 EXIT();
4698 return 0;
4699}
4700
4701/**
4702 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4703 * to the CSR roam profile.
4704 *
4705 * @dev: Pointer to the net device.
4706 * @info: Pointer to the iw_request_info.
4707 * @wrqu: Pointer to the iwreq_data.
4708 * @extra: Pointer to the data.
4709 *
4710 * Return: 0 for success, error number on failure
4711 */
4712static int __iw_set_essid(struct net_device *dev,
4713 struct iw_request_info *info,
4714 union iwreq_data *wrqu, char *extra)
4715{
4716 unsigned long rc;
4717 uint32_t status = 0;
4718 hdd_wext_state_t *pWextState;
4719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4720 hdd_context_t *hdd_ctx;
4721 uint32_t roamId;
4722 tCsrRoamProfile *pRoamProfile;
4723 eMib_dot11DesiredBssType connectedBssType;
4724 eCsrAuthType RSNAuthType;
4725 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4726 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4727 int ret;
4728
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004729 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004730
4731 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4732 ret = wlan_hdd_validate_context(hdd_ctx);
4733 if (0 != ret)
4734 return ret;
4735
4736 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION &&
4737 pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) {
4738 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4739 hdd_device_mode_to_string(pAdapter->device_mode),
4740 pAdapter->device_mode);
4741 return -EINVAL;
4742 }
4743
4744 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4745
4746 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4747 hddLog(LOG2, FL("Counter measure is in progress"));
4748 return -EBUSY;
4749 }
4750 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4751 return -EINVAL;
4752
4753 pRoamProfile = &pWextState->roamProfile;
4754 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4755 (eMib_dot11DesiredBssType_independent ==
4756 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304757 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004758
4759 /* Need to issue a disconnect to CSR. */
4760 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304761 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004762 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4763
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304764 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004765 rc = wait_for_completion_timeout(&pAdapter->
4766 disconnect_comp_var,
4767 msecs_to_jiffies
4768 (WLAN_WAIT_TIME_DISCONNECT));
4769 if (!rc)
4770 hddLog(LOGE, FL("Disconnect event timed out"));
4771 }
4772 }
4773
4774 /*
4775 * when cfg80211 defined, wpa_supplicant wext driver uses
4776 * zero-length, null-string ssid for force disconnection.
4777 * after disconnection (if previously connected) and cleaning ssid,
4778 * driver MUST return success.
4779 */
4780 if (0 == wrqu->essid.length)
4781 return 0;
4782
4783 status = hdd_wmm_get_uapsd_mask(pAdapter,
4784 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304785 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004786 pWextState->roamProfile.uapsd_mask = 0;
4787
4788 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4789
4790 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4791 wrqu->essid.length;
4792
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304793 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004794 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304795 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004796 ssId), extra, wrqu->essid.length);
4797 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4798 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4799
4800 /* set gen ie */
4801 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4802
4803 /* set auth */
4804 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4805 }
4806#ifdef FEATURE_WLAN_WAPI
4807 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4808 if (pAdapter->wapi_info.nWapiMode) {
4809 switch (pAdapter->wapi_info.wapiAuthMode) {
4810 case WAPI_AUTH_MODE_PSK:
4811 {
4812 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4813 pAdapter->wapi_info.wapiAuthMode);
4814 pRoamProfile->AuthType.numEntries = 1;
4815 pRoamProfile->AuthType.authType[0] =
4816 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4817 break;
4818 }
4819 case WAPI_AUTH_MODE_CERT:
4820 {
4821 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4822 pAdapter->wapi_info.wapiAuthMode);
4823 pRoamProfile->AuthType.numEntries = 1;
4824 pRoamProfile->AuthType.authType[0] =
4825 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4826 break;
4827 }
4828 } /* End of switch */
4829 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4830 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4831 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4832 pRoamProfile->EncryptionType.numEntries = 1;
4833 pRoamProfile->EncryptionType.encryptionType[0] =
4834 eCSR_ENCRYPT_TYPE_WPI;
4835 pRoamProfile->mcEncryptionType.numEntries = 1;
4836 pRoamProfile->mcEncryptionType.encryptionType[0] =
4837 eCSR_ENCRYPT_TYPE_WPI;
4838 }
4839 }
4840#endif /* FEATURE_WLAN_WAPI */
4841 /* if previous genIE is not NULL, update AssocIE */
4842 if (0 != pWextState->genIE.length) {
4843 memset(&pWextState->assocAddIE, 0,
4844 sizeof(pWextState->assocAddIE));
4845 memcpy(pWextState->assocAddIE.addIEdata,
4846 pWextState->genIE.addIEdata, pWextState->genIE.length);
4847 pWextState->assocAddIE.length = pWextState->genIE.length;
4848 pWextState->roamProfile.pAddIEAssoc =
4849 pWextState->assocAddIE.addIEdata;
4850 pWextState->roamProfile.nAddIEAssocLength =
4851 pWextState->assocAddIE.length;
4852
4853 /* clear previous genIE after use it */
4854 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4855 }
4856
4857 /*
4858 * Assumes it is not WPS Association by default, except when
4859 * pAddIEAssoc has WPS IE.
4860 */
4861 pWextState->roamProfile.bWPSAssociation = false;
4862
4863 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4864 pWextState->roamProfile.
4865 nAddIEAssocLength))
4866 pWextState->roamProfile.bWPSAssociation = true;
4867
4868 /* Disable auto BMPS entry by PMC until DHCP is done */
4869 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
4870 true);
4871
4872 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
4873
4874 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
4875 hdd_select_cbmode(pAdapter,
4876 (WLAN_HDD_GET_CTX(pAdapter))->config->
4877 AdHocChannel5G);
4878 }
4879 status = sme_roam_connect(hHal, pAdapter->sessionId,
4880 &(pWextState->roamProfile), &roamId);
4881 pRoamProfile->ChannelInfo.ChannelList = NULL;
4882 pRoamProfile->ChannelInfo.numOfChannels = 0;
4883
4884 EXIT();
4885 return status;
4886}
4887
4888/**
4889 * iw_set_essid() - set essid handler function
4890 * @dev: Pointer to the net device.
4891 * @info: Pointer to the iw_request_info.
4892 * @wrqu: Pointer to the iwreq_data.
4893 * @extra: Pointer to the data.
4894 *
4895 * Return: 0 for success, error number on failure
4896 */
4897int iw_set_essid(struct net_device *dev,
4898 struct iw_request_info *info,
4899 union iwreq_data *wrqu, char *extra)
4900{
4901 int ret;
4902
4903 cds_ssr_protect(__func__);
4904 ret = __iw_set_essid(dev, info, wrqu, extra);
4905 cds_ssr_unprotect(__func__);
4906
4907 return ret;
4908}
4909
4910/**
4911 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
4912 * @dev: pointer to the net device
4913 * @info: pointer to the iw request info
4914 * @dwrq: pointer to iw_point
4915 * @extra: pointer to the data
4916 *
4917 * Return: 0 on success, error number otherwise
4918 */
4919static int __iw_get_essid(struct net_device *dev,
4920 struct iw_request_info *info,
4921 struct iw_point *dwrq, char *extra)
4922{
4923 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4924 hdd_context_t *hdd_ctx;
4925 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4926 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4927 int ret;
4928
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004929 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004930
4931 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4932 ret = wlan_hdd_validate_context(hdd_ctx);
4933 if (0 != ret)
4934 return ret;
4935
4936 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
4937 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
4938 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
4939 || pHddStaCtx->conn_info.connState ==
4940 eConnectionState_IbssDisconnected)
4941 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
4942 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
4943 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
4944 dwrq->length);
4945 dwrq->flags = 1;
4946 } else {
4947 memset(extra, 0, dwrq->length);
4948 dwrq->length = 0;
4949 dwrq->flags = 0;
4950 }
4951 EXIT();
4952 return 0;
4953}
4954
4955/**
4956 * iw_get_essid() - get essid handler function
4957 * @dev: Pointer to the net device.
4958 * @info: Pointer to the iw_request_info.
4959 * @wrqu: Pointer to the iwreq_data.
4960 * @extra: Pointer to the data.
4961 *
4962 * Return: 0 for success, error number on failure
4963 */
4964int iw_get_essid(struct net_device *dev,
4965 struct iw_request_info *info,
4966 struct iw_point *wrqu, char *extra)
4967{
4968 int ret;
4969
4970 cds_ssr_protect(__func__);
4971 ret = __iw_get_essid(dev, info, wrqu, extra);
4972 cds_ssr_unprotect(__func__);
4973
4974 return ret;
4975}
4976
4977/**
4978 * __iw_set_auth() -
4979 * This function sets the auth type received from the wpa_supplicant
4980 * @dev: pointer to the net device
4981 * @info: pointer to the iw request info
4982 * @wrqu: pointer to iwreq_data
4983 * @extra: pointer to the data
4984 *
4985 * Return: 0 on success, error number otherwise
4986 */
4987static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
4988 union iwreq_data *wrqu, char *extra)
4989{
4990 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4991 hdd_context_t *hdd_ctx;
4992 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4993 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4994 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4995 eCsrEncryptionType mcEncryptionType;
4996 eCsrEncryptionType ucEncryptionType;
4997 int ret;
4998
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004999 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005000
5001 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5002 ret = wlan_hdd_validate_context(hdd_ctx);
5003 if (0 != ret)
5004 return ret;
5005
5006 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5007 case IW_AUTH_WPA_VERSION:
5008 pWextState->wpaVersion = wrqu->param.value;
5009 break;
5010
5011 case IW_AUTH_CIPHER_PAIRWISE:
5012 {
5013 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5014 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5015 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5016 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5017 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5018 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5019 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5020 if ((IW_AUTH_KEY_MGMT_802_1X
5021 ==
5022 (pWextState->
5023 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5024 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5025 pHddStaCtx->conn_info.authType))
5026 /*Dynamic WEP key */
5027 ucEncryptionType =
5028 eCSR_ENCRYPT_TYPE_WEP40;
5029 else
5030 /*Static WEP key */
5031 ucEncryptionType =
5032 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5033 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5034 if ((IW_AUTH_KEY_MGMT_802_1X
5035 ==
5036 (pWextState->
5037 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5038 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5039 pHddStaCtx->conn_info.authType))
5040 /*Dynamic WEP key */
5041 ucEncryptionType =
5042 eCSR_ENCRYPT_TYPE_WEP104;
5043 else
5044 /*Static WEP key */
5045 ucEncryptionType =
5046 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5047 } else {
5048 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5049 wrqu->param.value);
5050 return -EINVAL;
5051 }
5052
5053 pRoamProfile->EncryptionType.numEntries = 1;
5054 pRoamProfile->EncryptionType.encryptionType[0] =
5055 ucEncryptionType;
5056 }
5057 break;
5058 case IW_AUTH_CIPHER_GROUP:
5059 {
5060 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5061 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5062 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5063 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5064 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5065 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5066 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5067 if ((IW_AUTH_KEY_MGMT_802_1X
5068 ==
5069 (pWextState->
5070 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5071 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5072 pHddStaCtx->conn_info.authType))
5073 mcEncryptionType =
5074 eCSR_ENCRYPT_TYPE_WEP40;
5075 else
5076 mcEncryptionType =
5077 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5078 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5079 /* Dynamic WEP keys won't work with shared keys */
5080 if ((IW_AUTH_KEY_MGMT_802_1X
5081 ==
5082 (pWextState->
5083 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5084 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5085 pHddStaCtx->conn_info.authType)) {
5086 mcEncryptionType =
5087 eCSR_ENCRYPT_TYPE_WEP104;
5088 } else {
5089 mcEncryptionType =
5090 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5091 }
5092 } else {
5093 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5094 wrqu->param.value);
5095 return -EINVAL;
5096 }
5097
5098 pRoamProfile->mcEncryptionType.numEntries = 1;
5099 pRoamProfile->mcEncryptionType.encryptionType[0] =
5100 mcEncryptionType;
5101 }
5102 break;
5103
5104 case IW_AUTH_80211_AUTH_ALG:
5105 {
5106 /* Save the auth algo here and set auth type to SME Roam profile
5107 in the iw_set_ap_address */
5108 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5109 pHddStaCtx->conn_info.authType =
5110 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5111
5112 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5113 pHddStaCtx->conn_info.authType =
5114 eCSR_AUTH_TYPE_SHARED_KEY;
5115
5116 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5117 /*Not supported */
5118 pHddStaCtx->conn_info.authType =
5119 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5120 pWextState->roamProfile.AuthType.authType[0] =
5121 pHddStaCtx->conn_info.authType;
5122 }
5123 break;
5124
5125 case IW_AUTH_KEY_MGMT:
5126 {
5127#ifdef FEATURE_WLAN_ESE
5128#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5129 /*Check for CCKM AKM type */
5130 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5131 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5132 /* Set the CCKM bit in authKeyMgmt */
5133 /*
5134 * Right now, this breaks all ref to authKeyMgmt because
5135 * our code doesn't realize it is a "bitfield"
5136 */
5137 pWextState->authKeyMgmt |=
5138 IW_AUTH_KEY_MGMT_CCKM;
5139 /* Set the key management to 802.1X */
5140 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5141 pWextState->isESEConnection = true;
5142 /*
5143 * This is test code. I need to actually KNOW whether
5144 * this is an RSN Assoc or WPA.
5145 */
5146 pWextState->collectedAuthType =
5147 eCSR_AUTH_TYPE_CCKM_RSN;
5148 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5149 /* Save the key management */
5150 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5151 pWextState->collectedAuthType =
5152 eCSR_AUTH_TYPE_RSN;
5153 } else
5154 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5155 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5156 /* Save the key management anyway */
5157 pWextState->authKeyMgmt = wrqu->param.value;
5158 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5159 /* Save the key management */
5160 pWextState->authKeyMgmt |=
5161 IW_AUTH_KEY_MGMT_802_1X;
5162 pWextState->collectedAuthType =
5163 eCSR_AUTH_TYPE_RSN;
5164 }
5165#else
5166 /* Save the key management */
5167 pWextState->authKeyMgmt = wrqu->param.value;
5168#endif /* FEATURE_WLAN_ESE */
5169 }
5170 break;
5171
5172 case IW_AUTH_TKIP_COUNTERMEASURES:
5173 {
5174 if (wrqu->param.value) {
5175 hddLog(LOG2,
5176 "Counter Measure started %d",
5177 wrqu->param.value);
5178 pWextState->mTKIPCounterMeasures =
5179 TKIP_COUNTER_MEASURE_STARTED;
5180 } else {
5181 hddLog(LOG2,
5182 "Counter Measure stopped=%d",
5183 wrqu->param.value);
5184 pWextState->mTKIPCounterMeasures =
5185 TKIP_COUNTER_MEASURE_STOPED;
5186 }
5187 }
5188 break;
5189 case IW_AUTH_DROP_UNENCRYPTED:
5190 case IW_AUTH_WPA_ENABLED:
5191 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5192 case IW_AUTH_ROAMING_CONTROL:
5193 case IW_AUTH_PRIVACY_INVOKED:
5194
5195 default:
5196
5197 hddLog(LOGW, FL("called with unsupported auth type %d"),
5198 wrqu->param.flags & IW_AUTH_INDEX);
5199 break;
5200 }
5201
5202 EXIT();
5203 return 0;
5204}
5205
5206/**
5207 * iw_set_auth() - set auth callback function
5208 * @dev: Pointer to the net device.
5209 * @info: Pointer to the iw_request_info.
5210 * @wrqu: Pointer to the iwreq_data.
5211 * @extra: Pointer to the data.
5212 *
5213 * Return: 0 for success, error number on failure.
5214 */
5215int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5216 union iwreq_data *wrqu, char *extra)
5217{
5218 int ret;
5219
5220 cds_ssr_protect(__func__);
5221 ret = __iw_set_auth(dev, info, wrqu, extra);
5222 cds_ssr_unprotect(__func__);
5223
5224 return ret;
5225}
5226
5227/**
5228 * __iw_get_auth() -
5229 * This function returns the auth type to the wpa_supplicant
5230 * @dev: pointer to the net device
5231 * @info: pointer to the iw request info
5232 * @wrqu: pointer to iwreq_data
5233 * @extra: pointer to the data
5234 *
5235 * Return: 0 on success, error number otherwise
5236 */
5237static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5238 union iwreq_data *wrqu, char *extra)
5239{
5240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5241 hdd_context_t *hdd_ctx;
5242 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5243 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5244 int ret;
5245
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005246 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005247
5248 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5249 ret = wlan_hdd_validate_context(hdd_ctx);
5250 if (0 != ret)
5251 return ret;
5252
5253 switch (pRoamProfile->negotiatedAuthType) {
5254 case eCSR_AUTH_TYPE_WPA_NONE:
5255 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5256 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5257 break;
5258 case eCSR_AUTH_TYPE_WPA:
5259 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5260 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5261 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005262
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005263 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005264 case eCSR_AUTH_TYPE_RSN:
5265 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5266 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5267 break;
5268 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5269 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5270 break;
5271 case eCSR_AUTH_TYPE_SHARED_KEY:
5272 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5273 break;
5274 case eCSR_AUTH_TYPE_UNKNOWN:
5275 hddLog(LOG1, FL("called with unknown auth type"));
5276 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5277 break;
5278 case eCSR_AUTH_TYPE_AUTOSWITCH:
5279 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5280 break;
5281 case eCSR_AUTH_TYPE_WPA_PSK:
5282 hddLog(LOG1, FL("called with WPA PSK auth type"));
5283 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5284 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005285
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005286 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005287 case eCSR_AUTH_TYPE_RSN_PSK:
5288#ifdef WLAN_FEATURE_11W
5289 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5290 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5291#endif
5292 hddLog(LOG1, FL("called with RSN PSK auth type"));
5293 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5294 return -EIO;
5295 default:
5296 hddLog(LOGE, FL("called with unknown auth type"));
5297 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5298 return -EIO;
5299 }
5300 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5301 switch (pRoamProfile->negotiatedUCEncryptionType) {
5302 case eCSR_ENCRYPT_TYPE_NONE:
5303 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5304 break;
5305 case eCSR_ENCRYPT_TYPE_WEP40:
5306 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5307 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5308 break;
5309 case eCSR_ENCRYPT_TYPE_TKIP:
5310 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5311 break;
5312 case eCSR_ENCRYPT_TYPE_WEP104:
5313 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5314 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5315 break;
5316 case eCSR_ENCRYPT_TYPE_AES:
5317 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5318 break;
5319 default:
5320 hddLog(LOG1, FL("called with unknown auth type %d"),
5321 pRoamProfile->negotiatedUCEncryptionType);
5322 return -EIO;
5323 }
5324 }
5325
5326 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5327 switch (pRoamProfile->negotiatedMCEncryptionType) {
5328 case eCSR_ENCRYPT_TYPE_NONE:
5329 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5330 break;
5331 case eCSR_ENCRYPT_TYPE_WEP40:
5332 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5333 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5334 break;
5335 case eCSR_ENCRYPT_TYPE_TKIP:
5336 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5337 break;
5338 case eCSR_ENCRYPT_TYPE_WEP104:
5339 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5340 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5341 break;
5342 case eCSR_ENCRYPT_TYPE_AES:
5343 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5344 break;
5345 default:
5346 hddLog(LOG1, FL("called with unknown auth type %d"),
5347 pRoamProfile->negotiatedMCEncryptionType);
5348 return -EIO;
5349 }
5350 }
5351
5352 hddLog(LOG1, FL("called with auth type %d"),
5353 pRoamProfile->AuthType.authType[0]);
5354 EXIT();
5355 return 0;
5356}
5357
5358/**
5359 * iw_get_auth() - get auth callback function
5360 * @dev: Pointer to the net device.
5361 * @info: Pointer to the iw_request_info.
5362 * @wrqu: Pointer to the iwreq_data.
5363 * @extra: Pointer to the data.
5364 *
5365 * Return: 0 for success, error number on failure.
5366 */
5367int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5368 union iwreq_data *wrqu, char *extra)
5369{
5370 int ret;
5371
5372 cds_ssr_protect(__func__);
5373 ret = __iw_get_auth(dev, info, wrqu, extra);
5374 cds_ssr_unprotect(__func__);
5375
5376 return ret;
5377}
5378
5379/**
5380 * __iw_set_ap_address() - set ap address
5381 * @dev: pointer to the net device
5382 * @info: pointer to the iw request info
5383 * @wrqu: pointer to iwreq_data
5384 * @extra: pointer to the data
5385 *
5386 * This function updates the HDD global station context connection info
5387 * BSSID with the MAC address received from the wpa_supplicant.
5388 *
5389 * Return: 0 on success, error number otherwise
5390 */
5391static int __iw_set_ap_address(struct net_device *dev,
5392 struct iw_request_info *info,
5393 union iwreq_data *wrqu, char *extra)
5394{
5395
5396 hdd_adapter_t *adapter;
5397 hdd_context_t *hdd_ctx;
5398 hdd_station_ctx_t *pHddStaCtx =
5399 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5400 uint8_t *pMacAddress = NULL;
5401 int ret;
5402
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005403 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005404
5405 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5406
5407 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5408 ret = wlan_hdd_validate_context(hdd_ctx);
5409 if (0 != ret)
5410 return ret;
5411
5412 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5413 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305414 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305415 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005416 EXIT();
5417
5418 return 0;
5419}
5420
5421/**
5422 * iw_set_ap_address() - set ap addresses callback function
5423 * @dev: Pointer to the net device.
5424 * @info: Pointer to the iw_request_info.
5425 * @wrqu: Pointer to the iwreq_data.
5426 * @extra: Pointer to the data.
5427 *
5428 * Return: 0 for success, error number on failure.
5429 */
5430int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5431 union iwreq_data *wrqu, char *extra)
5432{
5433 int ret;
5434
5435 cds_ssr_protect(__func__);
5436 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5437 cds_ssr_unprotect(__func__);
5438
5439 return ret;
5440}
5441
5442/**
5443 * __iw_get_ap_address() - get ap address
5444 * @dev: pointer to the net device
5445 * @info: pointer to the iw request info
5446 * @wrqu: pointer to iwreq_data
5447 * @extra: pointer to the data
5448 *
5449 * This function returns currently associated BSSID.
5450 *
5451 * Return: 0 on success, error number otherwise
5452 */
5453static int __iw_get_ap_address(struct net_device *dev,
5454 struct iw_request_info *info,
5455 union iwreq_data *wrqu, char *extra)
5456{
5457 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5458 hdd_context_t *hdd_ctx;
5459 hdd_station_ctx_t *pHddStaCtx =
5460 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5461 int ret;
5462
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005463 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005464
5465 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5466 ret = wlan_hdd_validate_context(hdd_ctx);
5467 if (0 != ret)
5468 return ret;
5469
5470 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5471 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305472 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005473 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305474 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005475 } else {
5476 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5477 }
5478 EXIT();
5479 return 0;
5480}
5481
5482/**
5483 * iw_get_ap_address() - get ap addresses callback function
5484 * @dev: Pointer to the net device.
5485 * @info: Pointer to the iw_request_info.
5486 * @wrqu: Pointer to the iwreq_data.
5487 * @extra: Pointer to the data.
5488 *
5489 * Return: 0 for success, error number on failure.
5490 */
5491int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5492 union iwreq_data *wrqu, char *extra)
5493{
5494 int ret;
5495
5496 cds_ssr_protect(__func__);
5497 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5498 cds_ssr_unprotect(__func__);
5499
5500 return ret;
5501}