blob: 5d2c4b662c81863bb02895d9c3a77b5bec69ee77 [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);
820 cds_decr_session_set_pcl(
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800821 pAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800823 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824
825#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
826 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
827#endif
828
829 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530830 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831 &pHddStaCtx->conn_info.bssId);
832
833 /* send peer status indication to oem app */
834 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
835 ePeerDisconnected, 0,
836 pAdapter->sessionId,
837 NULL);
838 }
839#ifdef WLAN_FEATURE_LPSS
840 pAdapter->rssi_send = false;
841 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
842#endif
843#ifdef FEATURE_WLAN_TDLS
844 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) &&
845 (pCsrRoamInfo)) {
846 hddLog(LOG4,
847 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
848 pCsrRoamInfo->tdls_prohibited,
849 pCsrRoamInfo->tdls_chan_swit_prohibited);
850
851 wlan_hdd_update_tdls_info(pAdapter,
852 pCsrRoamInfo->tdls_prohibited,
853 pCsrRoamInfo->tdls_chan_swit_prohibited);
854 }
855#endif
856#ifdef MSM_PLATFORM
857 /* stop timer in sta/p2p_cli */
858 spin_lock_bh(&pHddCtx->bus_bw_lock);
859 pAdapter->prev_tx_packets = 0;
860 pAdapter->prev_rx_packets = 0;
861 spin_unlock_bh(&pHddCtx->bus_bw_lock);
862 hdd_stop_bus_bw_compute_timer(pAdapter);
863#endif
864 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800865 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 /* Send SCC/MCC Switching event to IPA */
867 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
868
869 msg = NULL;
870 /*During the WLAN uninitialization,supplicant is stopped before the
871 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800872 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873 wireless_send_event(dev, we_event, &wrqu, msg);
874#ifdef FEATURE_WLAN_ESE
875 if (eConnectionState_Associated ==
876 pHddStaCtx->conn_info.connState) {
877 if ((pRoamProfile->AuthType.authType[0] ==
878 eCSR_AUTH_TYPE_CCKM_RSN) ||
879 (pRoamProfile->AuthType.authType[0] ==
880 eCSR_AUTH_TYPE_CCKM_WPA))
881 hdd_send_new_ap_channel_info(dev, pAdapter,
882 pCsrRoamInfo);
883 }
884#endif
885 }
886}
887
888/**
889 * hdd_conn_remove_connect_info() - remove connection info
890 * @pHddStaCtx: pointer to global HDD station context
891 * @pCsrRoamInfo: pointer to roam info
892 *
893 * Return: none
894 */
895static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
896{
897 /* Remove staId, bssId and peerMacAddress */
898 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530899 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
900 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530901 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800902
903 /* Clear all security settings */
904 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
905 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
906 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
907
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530908 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
909 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800910
911 /* Set not-connected state */
912 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
913 pHddStaCtx->conn_info.proxyARPService = 0;
914
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530915 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800916}
917
918/**
919 * hdd_roam_deregister_sta() - deregister station
920 * @pAdapter: pointer to adapter
921 * @staId: station identifier
922 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530923 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800924 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530925static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800926hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
927{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530928 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800929 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
930
931 if (eConnectionState_IbssDisconnected ==
932 pHddStaCtx->conn_info.connState) {
933 /*
934 * Do not set the carrier off when the last peer leaves.
935 * We will set the carrier off while stopping the IBSS.
936 */
937 }
938
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530939 qdf_status = ol_txrx_clear_peer(staId);
940 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800941 hddLog(LOGE,
942 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530943 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530945 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800946}
947
948/**
949 * hdd_dis_connect_handler() - disconnect event handler
950 * @pAdapter: pointer to adapter
951 * @pRoamInfo: pointer to roam info
952 * @roamId: roam identifier
953 * @roamStatus: roam status
954 * @roamResult: roam result
955 *
956 * This function handles disconnect event:
957 * 1. Disable transmit queues;
958 * 2. Clean up internal connection states and data structures;
959 * 3. Send disconnect indication to supplicant.
960 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530961 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800962 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530963static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800964 tCsrRoamInfo *pRoamInfo,
965 uint32_t roamId,
966 eRoamCmdStatus roamStatus,
967 eCsrRoamResult roamResult)
968{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530969 QDF_STATUS status = QDF_STATUS_SUCCESS;
970 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971 struct net_device *dev = pAdapter->dev;
972 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
973 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
974 uint8_t sta_id;
975 bool sendDisconInd = true;
976
977 if (dev == NULL) {
978 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530979 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800980 }
981 /* notify apps that we can't pass traffic anymore */
982 hddLog(LOG1, FL("Disabling queues"));
983 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
984 WLAN_CONTROL_PATH);
985
986 if (hdd_ipa_is_enabled(pHddCtx))
987 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
988 WLAN_STA_DISCONNECT,
989 pHddStaCtx->conn_info.bssId.bytes);
990
991#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
992 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
993#endif
994
995#ifdef QCA_PKT_PROTO_TRACE
996 /* STA disconnected, update into trace buffer */
997 if (pHddCtx->config->gEnableDebugLog)
998 cds_pkt_trace_buf_update("ST:DISASC");
999#endif /* QCA_PKT_PROTO_TRACE */
1000
1001 /* HDD has initiated disconnect, do not send disconnect indication
1002 * to kernel. Sending disconnected event to kernel for userspace
1003 * initiated disconnect will be handled by hdd_DisConnectHandler call
1004 * to cfg80211_disconnected.
1005 */
1006 if ((eConnectionState_Disconnecting ==
1007 pHddStaCtx->conn_info.connState) ||
1008 (eConnectionState_NotConnected ==
1009 pHddStaCtx->conn_info.connState)) {
1010 hddLog(LOG1,
1011 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1012 sendDisconInd = false;
1013 }
1014
1015 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1016 INIT_COMPLETION(pAdapter->disconnect_comp_var);
1017 hddLog(LOG1,
1018 FL("Set HDD connState to eConnectionState_Disconnecting"));
1019 hdd_conn_set_connection_state(pAdapter,
1020 eConnectionState_Disconnecting);
1021 }
1022
1023 hdd_clear_roam_profile_ie(pAdapter);
1024 hdd_wmm_init(pAdapter);
1025
1026 /* indicate 'disconnect' status to wpa_supplicant... */
1027 hdd_send_association_event(dev, pRoamInfo);
1028 /* indicate disconnected event to nl80211 */
1029 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1030 /*
1031 * Only send indication to kernel if not initiated
1032 * by kernel
1033 */
1034 if (sendDisconInd) {
1035 /*
1036 * To avoid wpa_supplicant sending "HANGED" CMD
1037 * to ICS UI.
1038 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001039 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1040 if (pRoamInfo->reasonCode ==
1041 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1042 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043 cfg80211_disconnected(dev, pRoamInfo->
Ryan Hsua335c162016-01-21 12:12:20 -08001044 reasonCode, NULL, 0,
1045#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1046 true,
1047#endif
1048 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001049 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001050 cfg80211_disconnected(dev,
Ryan Hsua335c162016-01-21 12:12:20 -08001051 WLAN_REASON_UNSPECIFIED, NULL, 0,
1052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1053 true,
1054#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001056 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057
1058 hdd_info("sent disconnected event to nl80211, rssi: %d",
1059 pAdapter->rssi);
1060 }
1061 /*
1062 * During the WLAN uninitialization,supplicant is stopped
1063 * before the driver so not sending the status of the
1064 * connection to supplicant.
1065 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001066 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001067#ifdef WLAN_FEATURE_P2P_DEBUG
1068 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1069 if (global_p2p_connection_status ==
1070 P2P_CLIENT_CONNECTED_STATE_1) {
1071 global_p2p_connection_status =
1072 P2P_CLIENT_DISCONNECTED_STATE;
1073 hddLog(LOGE,
1074 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1075 } else if (global_p2p_connection_status ==
1076 P2P_CLIENT_COMPLETED_STATE) {
1077 global_p2p_connection_status =
1078 P2P_NOT_ACTIVE;
1079 hddLog(LOGE,
1080 "[P2P State] P2P Client is removed and moved to inactive state");
1081 }
1082 }
1083#endif
1084
1085 }
1086 }
1087
1088 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001089 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001090 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301091 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301092 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001093 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301094 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301095 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1096 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301097 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001098 }
1099 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301100 /* Clear all the peer sta register with TL. */
1101 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1102 if (0 == pHddStaCtx->conn_info.staId[i])
1103 continue;
1104 sta_id = pHddStaCtx->conn_info.staId[i];
1105 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1106 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301107 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301108 hddLog(LOGE,
1109 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1110 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301111 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301112 }
1113 /* set the staid and peer mac as 0, all other
1114 * reset are done in hdd_connRemoveConnectInfo.
1115 */
1116 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301117 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301118 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301119 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1120 pHddCtx->sta_to_adapter[sta_id] = NULL;
1121 }
1122 } else {
1123 sta_id = pHddStaCtx->conn_info.staId[0];
1124 /* We should clear all sta register with TL,
1125 * for now, only one.
1126 */
1127 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301128 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301129 hddLog(LOGE,
1130 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1131 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301132 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301133 }
1134 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001135 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001136 /* Clear saved connection information in HDD */
1137 hdd_conn_remove_connect_info(pHddStaCtx);
1138 hddLog(LOG1, FL("Set HDD connState to eConnectionState_NotConnected"));
1139 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1140#ifdef WLAN_FEATURE_GTK_OFFLOAD
1141 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1142 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1143 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1144 sizeof(tSirGtkOffloadParams));
1145 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1146 }
1147#endif
1148
1149#ifdef FEATURE_WLAN_TDLS
1150 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1151 wlan_hdd_tdls_disconnection_callback(pAdapter);
1152#endif
1153
1154 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1155 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1156 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1157 (pAdapter),
1158 pAdapter->sessionId);
1159 }
1160 /* Unblock anyone waiting for disconnect to complete */
1161 complete(&pAdapter->disconnect_comp_var);
1162 return status;
1163}
1164
1165/**
1166 * hdd_set_peer_authorized_event() - set peer_authorized_event
1167 * @vdev_id: vdevid
1168 *
1169 * Return: None
1170 */
1171void hdd_set_peer_authorized_event(uint32_t vdev_id)
1172{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301173 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001174 hdd_adapter_t *adapter = NULL;
1175
1176 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1177 if (adapter == NULL) {
1178 hddLog(LOGE,
1179 "%s: Invalid vdev_id", __func__);
1180 }
1181 complete(&adapter->sta_authorized_event);
1182}
1183
1184/**
1185 * hdd_change_peer_state() - change peer state
1186 * @pAdapter: HDD adapter
1187 * @sta_state: peer state
1188 * @roam_synch_in_progress: roam synch in progress
1189 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301190 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001191 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301192QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001193 uint8_t sta_id,
1194 enum ol_txrx_peer_state sta_state,
1195 bool roam_synch_in_progress)
1196{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301197 QDF_STATUS err;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001198 uint8_t *peer_mac_addr;
Manjunathappa Prakash2593a642016-04-01 08:53:35 -07001199 struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001200 ol_txrx_vdev_handle vdev;
1201 ol_txrx_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001202
1203 if (!pdev) {
1204 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301205 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001206 }
1207
1208 if (sta_id >= WLAN_MAX_STA_COUNT) {
1209 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301210 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001211 }
1212
1213 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1214 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301215 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001216
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001217 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1218 if (peer_mac_addr == NULL) {
1219 hddLog(LOGE, "peer mac addr is NULL");
1220 return QDF_STATUS_E_FAULT;
1221 }
1222
1223 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301224 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001225 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301226 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001227 }
1228#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1229 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301230 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001231#endif
1232
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001233 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1235 /* make sure event is reset */
1236 INIT_COMPLETION(pAdapter->sta_authorized_event);
1237#endif
1238
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001239 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240 hdd_set_peer_authorized_event,
1241 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301242 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001243 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301244 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001245 }
1246
1247 if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1248 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1249#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
1250 unsigned long rc;
1251
1252 /* wait for event from firmware to set the event */
1253 rc = wait_for_completion_timeout(
1254 &pAdapter->sta_authorized_event,
1255 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1256 if (!rc) {
1257 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1258 __func__);
1259 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001260 vdev = ol_txrx_get_vdev_for_peer(peer);
1261 ol_txrx_vdev_unpause(vdev,
1262 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001263#endif
1264 }
1265 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301266 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267}
1268
1269/**
1270 * hdd_roam_register_sta() - register station
1271 * @pAdapter: pointer to adapter
1272 * @pRoamInfo: pointer to roam info
1273 * @staId: station identifier
1274 * @pPeerMacAddress: peer MAC address
1275 * @pBssDesc: pointer to BSS description
1276 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301277 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001278 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301279static QDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001280 tCsrRoamInfo *pRoamInfo,
1281 uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301282 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001283 tSirBssDescription *pBssDesc)
1284{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301285 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001286 struct ol_txrx_desc_type staDesc = { 0 };
1287 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Dhanashri Atre182b0272016-02-17 15:35:07 -08001288 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001289
1290 if (NULL == pBssDesc)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301291 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292
1293 /* Get the Station ID from the one saved during the association */
1294 staDesc.sta_id = staId;
1295
1296 /* set the QoS field appropriately */
1297 if (hdd_wmm_is_active(pAdapter))
1298 staDesc.is_qos_enabled = 1;
1299 else
1300 staDesc.is_qos_enabled = 0;
1301
1302#ifdef FEATURE_WLAN_WAPI
1303 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1304 pAdapter->wapi_info.fIsWapiSta);
1305 if (pAdapter->wapi_info.fIsWapiSta)
1306 staDesc.is_wapi_supported = 1;
1307 else
1308 staDesc.is_wapi_supported = 0;
1309#endif /* FEATURE_WLAN_WAPI */
1310
Dhanashri Atre50141c52016-04-07 13:15:29 -07001311 /* Register the vdev transmit and receive functions */
1312 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
1313 txrx_ops.rx.rx = hdd_rx_packet_cbk;
1314 ol_txrx_vdev_register(
1315 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
1316 pAdapter, &txrx_ops);
1317 pAdapter->tx_fn = txrx_ops.tx.tx;
1318
Dhanashri Atre182b0272016-02-17 15:35:07 -08001319 qdf_status = ol_txrx_register_peer(&staDesc);
1320
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301321 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001322 hddLog(LOGW,
1323 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301324 qdf_status, qdf_status);
1325 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001326 }
1327
1328 if (!pRoamInfo->fAuthRequired) {
1329 /*
1330 * Connections that do not need Upper layer auth, transition
1331 * TLSHIM directly to 'Authenticated' state
1332 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301333 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001335 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1337 pRoamInfo->roamSynchInProgress
1338#else
1339 false
1340#endif
1341 );
1342
1343 hdd_conn_set_authenticated(pAdapter, true);
1344 } else {
1345 hddLog(LOG3,
1346 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1347 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301348 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001349 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001350 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1352 pRoamInfo->roamSynchInProgress
1353#else
1354 false
1355#endif
1356 );
1357 hdd_conn_set_authenticated(pAdapter, false);
1358 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301359 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360}
1361
1362/**
1363 * hdd_send_re_assoc_event() - send reassoc event
1364 * @dev: pointer to net device
1365 * @pAdapter: pointer to adapter
1366 * @pCsrRoamInfo: pointer to roam info
1367 * @reqRsnIe: pointer to RSN Information element
1368 * @reqRsnLength: length of RSN IE
1369 *
1370 * Return: none
1371 */
1372static void hdd_send_re_assoc_event(struct net_device *dev,
1373 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1374 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1375{
1376 unsigned int len = 0;
1377 u8 *pFTAssocRsp = NULL;
1378 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001379 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001380 uint32_t rspRsnLength = 0;
1381 struct ieee80211_channel *chan;
1382 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1383 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1384 uint8_t *buf_ptr, ssid_ie_len;
1385 struct cfg80211_bss *bss = NULL;
1386 uint8_t *final_req_ie = NULL;
1387 tCsrRoamConnectedProfile roam_profile;
1388 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1389
1390 if (!rspRsnIe) {
1391 hddLog(LOGE, FL("Unable to allocate RSN IE"));
Naveen Rawatdafda292016-01-06 18:32:14 -08001392 goto done;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393 }
1394
Naveen Rawat14298b92015-11-25 16:27:41 -08001395 if (!assoc_req_ies) {
1396 hdd_err("Unable to allocate Assoc Req IE");
Naveen Rawatdafda292016-01-06 18:32:14 -08001397 goto done;
Naveen Rawat14298b92015-11-25 16:27:41 -08001398 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001399 if (pCsrRoamInfo == NULL) {
1400 hddLog(LOGE, FL("Invalid CSR roam info"));
1401 goto done;
1402 }
1403
1404 if (pCsrRoamInfo->nAssocRspLength == 0) {
1405 hddLog(LOGE, FL("Invalid assoc response length"));
1406 goto done;
1407 }
1408
1409 pFTAssocRsp =
1410 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1411 pCsrRoamInfo->nAssocReqLength);
1412 if (pFTAssocRsp == NULL)
1413 goto done;
1414
1415 /* pFTAssocRsp needs to point to the IEs */
1416 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1417 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1418 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1419
1420 /*
1421 * Active session count is decremented upon disconnection, but during
1422 * roaming, there is no disconnect indication and hence active session
1423 * count is not decremented.
1424 * After roaming is completed, active session count is incremented
1425 * as a part of connect indication but effectively after roaming the
1426 * active session count should still be the same and hence upon
1427 * successful reassoc decrement the active session count here.
1428 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001429 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
1430 cds_decr_session_set_pcl(
1431 pAdapter->device_mode,
1432 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001433
1434 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1435 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1436 rspRsnLength = len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301437 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1438 qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439
1440 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1441 (int)pCsrRoamInfo->pBssDesc->channelId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301442 qdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1444 &roam_profile);
1445 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1446 pCsrRoamInfo->bssid.bytes,
1447 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
Ryan Hsu535d16a2016-01-18 16:45:12 -08001448#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001449 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
Ryan Hsu535d16a2016-01-18 16:45:12 -08001450#else
1451 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
1452#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001453
1454 if (bss == NULL)
1455 hddLog(LOGE, FL("Get BSS returned NULL"));
1456 buf_ptr = buf_ssid_ie;
1457 *buf_ptr = SIR_MAC_SSID_EID;
1458 buf_ptr++;
1459 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1460 buf_ptr++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301461 qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001462 roam_profile.SSID.length);
1463 ssid_ie_len = 2 + roam_profile.SSID.length;
Jeff Johnson9991f472016-01-06 16:02:31 -08001464 hdd_notice("SSIDIE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301465 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001466 buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1468 if (final_req_ie == NULL)
1469 goto done;
1470 buf_ptr = final_req_ie;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301471 qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001472 buf_ptr += ssid_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301473 qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1474 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1475 qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001476 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
Jeff Johnson9991f472016-01-06 16:02:31 -08001477 hdd_notice("Req RSN IE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301478 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001479 final_req_ie, (ssid_ie_len + reqRsnLength));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001480 cfg80211_roamed_bss(dev, bss,
1481 final_req_ie, (ssid_ie_len + reqRsnLength),
1482 rspRsnIe, rspRsnLength, GFP_KERNEL);
1483
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301484 qdf_mem_copy(assoc_req_ies,
Naveen Rawat14298b92015-11-25 16:27:41 -08001485 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1486 pCsrRoamInfo->nAssocReqLength);
1487
1488 hdd_notice("ReAssoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301489 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001490 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1491
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001492 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001493 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1494 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001495 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496done:
Naveen Rawatdf0a7e72016-01-06 18:35:53 -08001497 sme_roam_free_connect_profile(&roam_profile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001498 if (final_req_ie)
1499 kfree(final_req_ie);
1500 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001501 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001502}
1503
1504/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301505 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001506 * @roaminfo - Roaming Information
Govind Singhedc5cda2015-10-23 17:11:35 +05301507 *
1508 * Return: roam sync status if roaming offloaded else false
1509 */
1510#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001511bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
Govind Singhedc5cda2015-10-23 17:11:35 +05301512{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001513 if (roaminfo)
1514 return roaminfo->roamSynchInProgress;
1515 else
1516 return false;
Govind Singhedc5cda2015-10-23 17:11:35 +05301517}
1518#endif
1519
1520
1521/**
1522 * hdd_change_sta_state_authenticated()-
1523 * This function changes STA state to authenticated
1524 * @adapter: pointer to the adapter structure.
1525 * @roaminfo: pointer to the RoamInfo structure.
1526 *
1527 * This is called from hdd_RoamSetKeyCompleteHandler
1528 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1529 *
1530 * Return: 0 on success and errno on failure
1531 */
1532static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1533 tCsrRoamInfo *roaminfo)
1534{
1535 int ret;
1536 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1537
1538 hddLog(LOG1,
1539 "Changing TL state to AUTHENTICATED for StaId= %d",
1540 hddstactx->conn_info.staId[0]);
1541
1542 /* Connections that do not need Upper layer authentication,
1543 * transition TL to 'Authenticated' state after the keys are set
1544 */
1545 ret = hdd_change_peer_state(adapter,
1546 hddstactx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001547 OL_TXRX_PEER_STATE_AUTH,
Govind Singhedc5cda2015-10-23 17:11:35 +05301548 hdd_is_roam_sync_in_progress(roaminfo));
1549 hdd_conn_set_authenticated(adapter, true);
1550 if ((WLAN_HDD_INFRA_STATION == adapter->device_mode) ||
1551 (WLAN_HDD_P2P_CLIENT == adapter->device_mode)) {
1552 sme_ps_enable_auto_ps_timer(
1553 WLAN_HDD_GET_HAL_CTX(adapter),
1554 adapter->sessionId,
1555 hddstactx->hdd_ReassocScenario);
1556 }
1557
1558 return ret;
1559}
1560
1561/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001562 * hdd_roam_set_key_complete_handler() - Update the security parameters
1563 * @pAdapter: pointer to adapter
1564 * @pRoamInfo: pointer to roam info
1565 * @roamId: roam id
1566 * @roamStatus: roam status
1567 * @roamResult: roam result
1568 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301569 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301571static QDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572 tCsrRoamInfo *pRoamInfo,
1573 uint32_t roamId,
1574 eRoamCmdStatus roamStatus,
1575 eCsrRoamResult roamResult)
1576{
1577 eCsrEncryptionType connectedCipherAlgo;
1578 bool fConnected = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301579 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1581 ENTER();
1582
1583 if (NULL == pRoamInfo) {
1584 hddLog(LOG2, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301585 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001586 }
1587 /*
1588 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1589 * then go to 'authenticated'. For all other authentication types
1590 * (those that do not require upper layer authentication) we can put TL
1591 * directly into 'authenticated' state.
1592 */
1593 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1594 MAC_ADDRESS_STR, roamStatus, roamResult,
1595 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1596
1597 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1598 &connectedCipherAlgo);
1599 if (fConnected) {
1600 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
1601 uint8_t staId;
1602
Anurag Chouhanc5548422016-02-24 18:33:27 +05301603 if (qdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604 pHddStaCtx->roam_info.roamingState =
1605 HDD_ROAM_STATE_NONE;
1606 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301607 qdf_status = hdd_ibss_get_sta_id(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001608 pHddStaCtx,
1609 &pRoamInfo->peerMac,
1610 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301611 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612 hddLog(LOG2,
1613 "WLAN TL STA Ptk Installed for STAID=%d",
1614 staId);
1615 pHddStaCtx->roam_info.roamingState =
1616 HDD_ROAM_STATE_NONE;
1617 }
1618 }
1619 } else {
1620 /*
1621 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301622 * HDD later.This routine is invoked twice.
1623 * 1)set PTK 2)set GTK.The following if
1624 * statement will be TRUE when setting GTK.
1625 * At this time we don't handle the state in detail.
1626 * Related CR: 174048 - TL not in authenticated state
1627 */
1628 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult)
1629 pHddStaCtx->conn_info.gtk_installed = true;
1630 else
1631 pHddStaCtx->conn_info.ptk_installed = true;
1632
1633 /* In WPA case move STA to authenticated when
1634 * ptk is installed.Earlier in WEP case STA
1635 * was moved to AUTHENTICATED prior to setting
1636 * the unicast key and it was resulting in sending
1637 * few un-encrypted packet. Now in WEP case
1638 * STA state will be moved to AUTHENTICATED
1639 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301641 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1642 eCSR_ENCRYPT_TYPE_WEP40) ||
1643 (pHddStaCtx->conn_info.ucEncryptionType ==
1644 eCSR_ENCRYPT_TYPE_WEP104) ||
1645 (pHddStaCtx->conn_info.ucEncryptionType ==
1646 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1647 (pHddStaCtx->conn_info.ucEncryptionType ==
1648 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1649 if (pHddStaCtx->conn_info.gtk_installed &&
1650 pHddStaCtx->conn_info.ptk_installed)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301651 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301652 hdd_change_sta_state_authenticated(pAdapter,
1653 pRoamInfo);
1654 } else if (pHddStaCtx->conn_info.ptk_installed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301655 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301656 hdd_change_sta_state_authenticated(pAdapter,
1657 pRoamInfo);
1658 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659
Govind Singhedc5cda2015-10-23 17:11:35 +05301660 if (pHddStaCtx->conn_info.gtk_installed &&
1661 pHddStaCtx->conn_info.ptk_installed) {
1662 pHddStaCtx->conn_info.gtk_installed = false;
1663 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001664 }
1665
1666 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301667 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668 }
1669 } else {
1670 /*
1671 * possible disassoc after issuing set key and waiting
1672 * set key complete.
1673 */
1674 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1675 }
1676
1677 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301678 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679}
1680
1681/**
1682 * hdd_perform_roam_set_key_complete() - perform set key complete
1683 * @pAdapter: pointer to adapter
1684 *
1685 * Return: none
1686 */
1687void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1688{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301689 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001690 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1691 tCsrRoamInfo roamInfo;
1692 roamInfo.fAuthRequired = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301693 qdf_mem_copy(roamInfo.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301694 pHddStaCtx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301695 qdf_mem_copy(roamInfo.peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301696 pHddStaCtx->roam_info.peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001697
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301698 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699 hdd_roam_set_key_complete_handler(pAdapter,
1700 &roamInfo,
1701 pHddStaCtx->roam_info.roamId,
1702 pHddStaCtx->roam_info.roamStatus,
1703 eCSR_ROAM_RESULT_AUTHENTICATED);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301704 if (qdf_ret_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001705 hddLog(LOGE, FL("Set Key complete failure"));
1706
1707 pHddStaCtx->roam_info.deferKeyComplete = false;
1708}
1709
1710/**
1711 * hdd_association_completion_handler() - association completion handler
1712 * @pAdapter: pointer to adapter
1713 * @pRoamInfo: pointer to roam info
1714 * @roamId: roam id
1715 * @roamStatus: roam status
1716 * @roamResult: roam result
1717 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301718 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301720static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 tCsrRoamInfo *pRoamInfo,
1722 uint32_t roamId,
1723 eRoamCmdStatus roamStatus,
1724 eCsrRoamResult roamResult)
1725{
1726 struct net_device *dev = pAdapter->dev;
1727 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1728 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301729 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1731 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732 int ft_carrier_on = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001733 bool hddDisconInProgress = false;
1734 unsigned long rc;
1735
1736 if (!pHddCtx) {
1737 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301738 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739 }
1740
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001741 /* HDD has initiated disconnect, do not send connect result indication
1742 * to kernel as it will be handled by __cfg80211_disconnect.
1743 */
1744 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1745 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1746 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1747 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1748 hddDisconInProgress = true;
1749 }
1750
1751 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1752 if (NULL == pRoamInfo) {
1753 hddLog(LOGE, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301754 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001755 }
1756 if (!hddDisconInProgress) {
1757 hddLog(LOG1, FL("Set HDD connState to eConnectionState_Associated"));
1758 hdd_conn_set_connection_state(pAdapter,
1759 eConnectionState_Associated);
1760 }
1761 /* Save the connection info from CSR... */
1762 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1763 eCSR_BSS_TYPE_INFRASTRUCTURE);
1764#ifdef FEATURE_WLAN_WAPI
1765 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1766 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1767 || pRoamInfo->u.pConnectedProfile->AuthType ==
1768 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1769 pAdapter->wapi_info.fIsWapiSta = 1;
1770 } else {
1771 pAdapter->wapi_info.fIsWapiSta = 0;
1772 }
1773#endif /* FEATURE_WLAN_WAPI */
1774
1775 /* Indicate 'connect' status to user space */
1776 hdd_send_association_event(dev, pRoamInfo);
1777
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001778 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001779 if (pHddCtx->miracast_value)
1780 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1781 }
1782
1783 /* Initialize the Linkup event completion variable */
1784 INIT_COMPLETION(pAdapter->linkup_event_var);
1785
1786 /*
1787 * Sometimes Switching ON the Carrier is taking time to activate
1788 * the device properly. Before allowing any packet to go up to
1789 * the application, device activation has to be ensured for
1790 * proper queue mapping by the kernel. we have registered net
1791 * device notifier for device change notification. With this we
1792 * will come to know that the device is getting
1793 * activated properly.
1794 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001795 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001796 /*
1797 * Enable Linkup Event Servicing which allows the net
1798 * device notifier to set the linkup event variable.
1799 */
1800 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001801
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001802 /* Switch on the Carrier to activate the device */
1803 wlan_hdd_netif_queue_control(pAdapter,
1804 WLAN_NETIF_CARRIER_ON,
1805 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001806
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001807 /*
1808 * Wait for the Link to up to ensure all the queues
1809 * are set properly by the kernel.
1810 */
1811 rc = wait_for_completion_timeout(
1812 &pAdapter->linkup_event_var,
1813 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1814 );
1815 if (!rc)
1816 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001817
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001818 /*
1819 * Disable Linkup Event Servicing - no more service
1820 * required from the net device notifier call.
1821 */
1822 pAdapter->isLinkUpSvcNeeded = false;
1823 } else {
1824 pHddStaCtx->ft_carrier_on = false;
1825 ft_carrier_on = true;
1826 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001827 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1828 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1829 else
1830 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1831 pRoamInfo->staId);
1832
1833 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1834
1835 if (hdd_ipa_is_enabled(pHddCtx))
1836 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1837 WLAN_STA_CONNECT,
1838 pRoamInfo->bssid.bytes);
1839
1840#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1841 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1842#endif
1843
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001844 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845 pAdapter);
1846
1847#ifdef FEATURE_WLAN_TDLS
1848 wlan_hdd_tdls_connection_callback(pAdapter);
1849#endif
1850
1851#ifdef QCA_PKT_PROTO_TRACE
1852 /* STA Associated, update into trace buffer */
1853 if (pHddCtx->config->gEnableDebugLog)
1854 cds_pkt_trace_buf_update("ST:ASSOC");
1855#endif /* QCA_PKT_PROTO_TRACE */
1856 /*
1857 * For reassoc, the station is already registered, all we need
1858 * is to change the state of the STA in TL.
1859 * If authentication is required (WPA/WPA2/DWEP), change TL to
1860 * CONNECTED instead of AUTHENTICATED.
1861 */
1862 if (!pRoamInfo->fReassocReq) {
1863 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864 u8 *pFTAssocRsp = NULL;
1865 unsigned int assocRsplen = 0;
1866 u8 *pFTAssocReq = NULL;
1867 unsigned int assocReqlen = 0;
1868 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001869 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1870 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1871
1872 /* add bss_id to cfg80211 data base */
1873 bss =
1874 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1875 pRoamInfo);
1876 if (NULL == bss) {
1877 pr_err("wlan: Not able to create BSS entry\n");
1878 wlan_hdd_netif_queue_control(pAdapter,
1879 WLAN_NETIF_CARRIER_OFF,
1880 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301881 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001882 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001883 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1884 eCSR_AUTH_TYPE_FT_RSN
1885 || pRoamInfo->u.pConnectedProfile->AuthType ==
1886 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1887
1888 /* Association Response */
1889 pFTAssocRsp =
1890 (u8 *) (pRoamInfo->pbFrames +
1891 pRoamInfo->nBeaconLength +
1892 pRoamInfo->nAssocReqLength);
1893 if (pFTAssocRsp != NULL) {
1894 /*
1895 * pFTAssocRsp needs to point to the IEs
1896 */
1897 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1898 hddLog(LOG1,
1899 FL("AssocRsp is now at %02x%02x"),
1900 (unsigned int)pFTAssocRsp[0],
1901 (unsigned int)pFTAssocRsp[1]);
1902 assocRsplen =
1903 pRoamInfo->nAssocRspLength -
1904 FT_ASSOC_RSP_IES_OFFSET;
1905 } else {
1906 hddLog(LOGE, FL("AssocRsp is NULL"));
1907 assocRsplen = 0;
1908 }
1909
1910 /* Association Request */
1911 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1912 pRoamInfo->nBeaconLength);
1913 if (pFTAssocReq != NULL) {
1914 if (!ft_carrier_on) {
1915 /*
1916 * pFTAssocReq needs to point to
1917 * the IEs
1918 */
1919 pFTAssocReq +=
1920 FT_ASSOC_REQ_IES_OFFSET;
1921 hddLog(LOG1,
1922 FL("pFTAssocReq is now at %02x%02x"),
1923 (unsigned int)
1924 pFTAssocReq[0],
1925 (unsigned int)
1926 pFTAssocReq[1]);
1927 assocReqlen =
1928 pRoamInfo->nAssocReqLength -
1929 FT_ASSOC_REQ_IES_OFFSET;
1930 } else {
1931 /*
1932 * This should contain only the
1933 * FTIEs
1934 */
1935 assocReqlen =
1936 pRoamInfo->nAssocReqLength;
1937 }
1938 } else {
1939 hddLog(LOGE, FL("AssocReq is NULL"));
1940 assocReqlen = 0;
1941 }
1942
1943 if (ft_carrier_on) {
1944 if (!hddDisconInProgress) {
1945 /*
1946 * After roaming is completed,
1947 * active session count is
1948 * incremented as a part of
1949 * connect indication but
1950 * effectively the active
1951 * session count should still
1952 * be the same and hence upon
1953 * successful reassoc
1954 * decrement the active session
1955 * count here.
1956 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001957 if (!hdd_is_roam_sync_in_progress
1958 (pRoamInfo))
1959 cds_decr_session_set_pcl
1960 (pAdapter->device_mode,
1961 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001962 hddLog(LOG1,
1963 FL("ft_carrier_on is %d, sending roamed indication"),
1964 ft_carrier_on);
1965 chan =
1966 ieee80211_get_channel
1967 (pAdapter->wdev.wiphy,
1968 (int)pRoamInfo->pBssDesc->
1969 channelId);
1970 hddLog(LOG1,
1971 "assocReqlen %d assocRsplen %d",
1972 assocReqlen,
1973 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08001974
1975 hdd_notice(
1976 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301977 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05301978 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301979 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001980 pFTAssocReq,
1981 assocReqlen);
1982
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 cfg80211_roamed(dev, chan,
1984 pRoamInfo->
1985 bssid.bytes,
1986 pFTAssocReq,
1987 assocReqlen,
1988 pFTAssocRsp,
1989 assocRsplen,
1990 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001991 wlan_hdd_send_roam_auth_event(
1992 pHddCtx,
1993 pRoamInfo->bssid.bytes,
1994 pFTAssocReq,
1995 assocReqlen,
1996 pFTAssocRsp,
1997 assocRsplen,
1998 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999 }
2000 if (sme_get_ftptk_state
2001 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2002 pAdapter->sessionId)) {
2003 sme_set_ftptk_state
2004 (WLAN_HDD_GET_HAL_CTX
2005 (pAdapter),
2006 pAdapter->sessionId,
2007 false);
2008 pRoamInfo->fAuthRequired =
2009 false;
2010
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302011 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002012 roam_info.bssid,
2013 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302014 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302015 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002016 roam_info.peerMac,
2017 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302018 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002019 pHddStaCtx->roam_info.roamId =
2020 roamId;
2021 pHddStaCtx->roam_info.
2022 roamStatus = roamStatus;
2023 pHddStaCtx->roam_info.
2024 deferKeyComplete = true;
2025 }
2026 } else if (!hddDisconInProgress) {
2027 hddLog(LOG1,
2028 FL("ft_carrier_on is %d, sending connect indication"),
2029 ft_carrier_on);
2030 cfg80211_connect_result(dev,
2031 pRoamInfo->
2032 bssid.bytes,
2033 pFTAssocReq,
2034 assocReqlen,
2035 pFTAssocRsp,
2036 assocRsplen,
2037 WLAN_STATUS_SUCCESS,
2038 GFP_KERNEL);
2039 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002040 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002041 /*
2042 * wpa supplicant expecting WPA/RSN IE in
2043 * connect result.
2044 */
2045 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2046 (pAdapter),
2047 pAdapter->sessionId,
2048 &reqRsnLength,
2049 reqRsnIe);
2050
2051 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2052 (pAdapter),
2053 pAdapter->sessionId,
2054 &rspRsnLength,
2055 rspRsnIe);
2056 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002057 if (ft_carrier_on)
2058 hdd_send_re_assoc_event(dev,
2059 pAdapter,
2060 pRoamInfo,
2061 reqRsnIe,
2062 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002063 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002064 hddLog(LOG1,
2065 FL("sending connect indication to nl80211:for bssid "
2066 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302067 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002068 MAC_ADDR_ARRAY
2069 (pRoamInfo->bssid.bytes),
2070 roamResult, roamStatus);
2071
2072 /* inform connect result to nl80211 */
2073 cfg80211_connect_result(dev,
2074 pRoamInfo->
2075 bssid.bytes,
2076 reqRsnIe,
2077 reqRsnLength,
2078 rspRsnIe,
2079 rspRsnLength,
2080 WLAN_STATUS_SUCCESS,
2081 GFP_KERNEL);
2082 }
2083 }
2084 }
2085 if (!hddDisconInProgress) {
2086 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002087 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002088 bss);
2089
2090 /*
2091 * Perform any WMM-related association
2092 * processing.
2093 */
2094 hdd_wmm_assoc(pAdapter, pRoamInfo,
2095 eCSR_BSS_TYPE_INFRASTRUCTURE);
2096
2097 /*
2098 * Start the Queue - Start tx queues before
2099 * hdd_roam_register_sta, since
2100 * hdd_roam_register_sta will flush any cached
2101 * data frames immediately.
2102 */
2103 hddLog(LOG1, FL("Enabling queues"));
2104 wlan_hdd_netif_queue_control(pAdapter,
2105 WLAN_WAKE_ALL_NETIF_QUEUE,
2106 WLAN_CONTROL_PATH);
2107
2108 /*
2109 * Register the Station with TL after associated
2110 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302111 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002112 pRoamInfo,
2113 pHddStaCtx->
2114 conn_info.
2115 staId[0],
2116 NULL,
2117 pRoamInfo->
2118 pBssDesc);
2119 }
2120 } else {
2121 /*
2122 * wpa supplicant expecting WPA/RSN IE in connect result
2123 * in case of reassociation also need to indicate it to
2124 * supplicant.
2125 */
2126 csr_roam_get_wpa_rsn_req_ie(
2127 WLAN_HDD_GET_HAL_CTX(pAdapter),
2128 pAdapter->sessionId,
2129 &reqRsnLength, reqRsnIe);
2130
2131 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2132 reqRsnIe, reqRsnLength);
2133 /* Reassoc successfully */
2134 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302135 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002136 hdd_change_peer_state(pAdapter,
2137 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002138 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002139#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2140 pRoamInfo->roamSynchInProgress
2141#else
2142 false
2143#endif
2144 );
2145 hdd_conn_set_authenticated(pAdapter, false);
2146 } else {
2147 hddLog(LOG2,
2148 FL("staId: %d Changing TL state to AUTHENTICATED"),
2149 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302150 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002151 hdd_change_peer_state(pAdapter,
2152 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002153 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002154#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2155 pRoamInfo->roamSynchInProgress
2156#else
2157 false
2158#endif
2159 );
2160 hdd_conn_set_authenticated(pAdapter, true);
2161 }
2162
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302163 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164 /*
2165 * Perform any WMM-related association
2166 * processing
2167 */
2168 hdd_wmm_assoc(pAdapter, pRoamInfo,
2169 eCSR_BSS_TYPE_INFRASTRUCTURE);
2170 }
2171
2172 /* Start the tx queues */
2173#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2174 if (pRoamInfo->roamSynchInProgress)
2175 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2176#endif
2177 hddLog(LOG1, FL("Enabling queues"));
2178 wlan_hdd_netif_queue_control(pAdapter,
2179 WLAN_WAKE_ALL_NETIF_QUEUE,
2180 WLAN_CONTROL_PATH);
2181 }
2182
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302183 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002184 hddLog(LOGE,
2185 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302186 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002187 }
2188#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302189 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002190 sizeof(pAdapter->hdd_stats.hddPmfStats));
2191#endif
2192 } else {
2193 hdd_wext_state_t *pWextState =
2194 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2195 if (pRoamInfo)
2196 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302197 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002198 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2199 roamResult, roamStatus);
2200 else
2201 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302202 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002203 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2204 roamResult, roamStatus);
2205
2206 /*
2207 * CR465478: Only send up a connection failure result when CSR
2208 * has completed operation - with a ASSOCIATION_FAILURE status.
2209 */
2210 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2211 && !hddDisconInProgress) {
2212 if (pRoamInfo)
2213 hddLog(LOGE,
2214 FL("send connect failure to nl80211: for bssid "
2215 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302216 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002217 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302218 roamResult, roamStatus,
2219 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002220 else
2221 hddLog(LOGE,
2222 FL("connect failed: for bssid "
2223 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302224 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002225 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2226 roamResult, roamStatus);
2227
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002228 /* inform association failure event to nl80211 */
2229 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2230 roamResult) {
2231 if (pRoamInfo)
2232 cfg80211_connect_result(dev,
2233 pRoamInfo->bssid.bytes,
2234 NULL, 0, NULL, 0,
2235 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2236 GFP_KERNEL);
2237 else
2238 cfg80211_connect_result(dev,
2239 pWextState->req_bssId.bytes,
2240 NULL, 0, NULL, 0,
2241 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2242 GFP_KERNEL);
2243 } else {
2244 if (pRoamInfo) {
2245 eCsrAuthType authType =
2246 pWextState->roamProfile.AuthType.
2247 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302248 eCsrEncryptionType encryption_type =
2249 pWextState->roamProfile.
2250 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002251 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302252 (((authType ==
2253 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002254 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302255 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2256 ((encryption_type ==
2257 eCSR_ENCRYPT_TYPE_WEP40) ||
2258 (encryption_type ==
2259 eCSR_ENCRYPT_TYPE_WEP104) ||
2260 (encryption_type ==
2261 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2262 (encryption_type ==
2263 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002264 /*
2265 * In case of OPEN-WEP or SHARED-WEP
2266 * authentication, send exact protocol
2267 * reason code. This enables user
2268 * applications to reconnect the station
2269 * with correct configuration.
2270 */
2271 cfg80211_connect_result(dev,
2272 pRoamInfo->bssid.bytes, NULL, 0,
2273 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302274 (isWep &&
2275 pRoamInfo->reasonCode) ?
2276 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002277 WLAN_STATUS_UNSPECIFIED_FAILURE,
2278 GFP_KERNEL);
2279 } else
2280 cfg80211_connect_result(dev,
2281 pWextState->req_bssId.bytes,
2282 NULL, 0, NULL, 0,
2283 WLAN_STATUS_UNSPECIFIED_FAILURE,
2284 GFP_KERNEL);
2285 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302286 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002287 }
2288
2289 if (pRoamInfo) {
2290 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2291 pRoamInfo->statusCode)
2292 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2293 pRoamInfo->statusCode)
2294 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2295 pRoamInfo->statusCode)) {
2296 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2297 pRoamInfo);
2298 }
2299 }
2300
2301 /*
2302 * Set connection state to eConnectionState_NotConnected only
2303 * when CSR has completed operation - with a
2304 * ASSOCIATION_FAILURE status.
2305 */
2306 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2307 && !hddDisconInProgress) {
2308 hddLog(LOG1,
2309 FL("state to eConnectionState_NotConnected"));
2310 hdd_conn_set_connection_state(pAdapter,
2311 eConnectionState_NotConnected);
2312 }
2313 hdd_wmm_init(pAdapter);
2314
2315 hddLog(LOG1, FL("Disabling queues"));
2316 wlan_hdd_netif_queue_control(pAdapter,
2317 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2318 WLAN_CONTROL_PATH);
2319 }
2320
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302321 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002322 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302323 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002324
Govind Singh24db1ed2015-12-18 15:54:59 +05302325 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2326 cds_force_sap_on_scc(roamResult,
2327 pRoamInfo->pBssDesc->channelId);
2328 } else {
2329 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302330 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302331 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002332
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302333 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334}
2335
2336/**
2337 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2338 * @pAdapter: pointer to adapter
2339 * @pRoamInfo: pointer to roam info
2340 * @roamId: roam id
2341 * @roamStatus: roam status
2342 * @roamResult: roam result
2343 *
2344 * Here we update the status of the Ibss when we receive information that we
2345 * have started/joined an ibss session.
2346 *
2347 * Return: none
2348 */
2349static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2350 tCsrRoamInfo *pRoamInfo,
2351 uint32_t roamId,
2352 eRoamCmdStatus roamStatus,
2353 eCsrRoamResult roamResult)
2354{
2355 hddLog(LOG1, "%s: id %d, status %d, result %d",
2356 pAdapter->dev->name, roamId, roamStatus, roamResult);
2357
2358 switch (roamResult) {
2359 /* both IBSS Started and IBSS Join should come in here. */
2360 case eCSR_ROAM_RESULT_IBSS_STARTED:
2361 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2362 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2363 {
2364 hdd_context_t *pHddCtx =
2365 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302366 hdd_station_ctx_t *hdd_sta_ctx =
2367 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302368 struct qdf_mac_addr broadcastMacAddr =
2369 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002370
2371 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302372 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002373 return;
2374 }
2375
2376 /* When IBSS Started comes from CSR, we need to move
2377 * connection state to IBSS Disconnected (meaning no peers
2378 * are in the IBSS).
2379 */
2380 hddLog(LOG1,
2381 FL("Set HDD connState to eConnectionState_IbssDisconnected"));
2382 hdd_conn_set_connection_state(pAdapter,
2383 eConnectionState_IbssDisconnected);
2384 /* notify wmm */
2385 hdd_wmm_connect(pAdapter, pRoamInfo,
2386 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302387
2388 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2389
2390 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002391 pAdapter;
2392 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302393 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002394 &broadcastMacAddr,
2395 pRoamInfo->pBssDesc);
2396
2397 if (pRoamInfo->pBssDesc) {
2398 struct cfg80211_bss *bss;
2399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2400 struct ieee80211_channel *chan;
2401 int chan_no;
2402 unsigned int freq;
2403#endif
2404 /* we created the IBSS, notify supplicant */
2405 hddLog(LOG1,
2406 FL("%s: created ibss " MAC_ADDRESS_STR),
2407 pAdapter->dev->name,
2408 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2409
2410 /* we must first give cfg80211 the BSS information */
2411 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2412 pRoamInfo);
2413 if (NULL == bss) {
2414 hddLog(LOGE,
2415 FL("%s: unable to create IBSS entry"),
2416 pAdapter->dev->name);
2417 return;
2418 }
2419 hddLog(LOG1, FL("Enabling queues"));
2420 wlan_hdd_netif_queue_control(pAdapter,
2421 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2422 WLAN_CONTROL_PATH);
2423
2424#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2425 chan_no = pRoamInfo->pBssDesc->channelId;
2426
2427 if (chan_no <= 14)
2428 freq = ieee80211_channel_to_frequency(chan_no,
2429 IEEE80211_BAND_2GHZ);
2430 else
2431 freq = ieee80211_channel_to_frequency(chan_no,
2432 IEEE80211_BAND_5GHZ);
2433
2434 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2435
2436 if (chan)
2437 cfg80211_ibss_joined(pAdapter->dev,
2438 bss->bssid, chan,
2439 GFP_KERNEL);
2440 else
2441 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2442 pAdapter->dev->name,
2443 (int)pRoamInfo->pBssDesc->channelId);
2444#else
2445 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2446 GFP_KERNEL);
2447#endif
2448 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002449 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002450 bss);
2451 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002452 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002453 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002454 pAdapter->sessionId);
2455 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2456 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002457 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002458 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002459 break;
2460 }
2461
2462 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2463 {
2464 hddLog(LOGE,
2465 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2466 break;
2467 }
2468
2469 default:
2470 hddLog(LOGE, FL("%s: unexpected result %d"),
2471 pAdapter->dev->name, (int)roamResult);
2472 break;
2473 }
2474
2475 return;
2476}
2477
2478/**
2479 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2480 * @pHddStaCtx: pointer to global HDD station context
2481 * @staId: station id
2482 * @peerMacAddress: pointer to peer MAC address
2483 *
2484 * This information is passed to iwconfig later. The peer that joined
2485 * last is passed as information to iwconfig.
2486 *
2487 * Return:
2488 * true if we add MAX_IBSS_PEERS or less STA
2489 * false otherwise.
2490 */
2491static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302492 struct qdf_mac_addr *peerMacAddress)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002493{
2494 bool fSuccess = false;
2495 int idx = 0;
2496
2497 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2498 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2499 pHddStaCtx->conn_info.staId[idx] = staId;
2500
Anurag Chouhanc5548422016-02-24 18:33:27 +05302501 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002502 peerMacAddress[idx], peerMacAddress);
2503
2504 fSuccess = true;
2505 break;
2506 }
2507 }
2508
2509 return fSuccess;
2510}
2511
2512/**
2513 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2514 * @pAdapter: pointer to adapter
2515 * @staId: station id
2516 *
2517 * Return:
2518 * true if we remove MAX_IBSS_PEERS or less STA
2519 * false otherwise.
2520 */
2521static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2522{
2523 bool fSuccess = false;
2524 int idx = 0;
2525 uint8_t valid_idx = 0;
2526 uint8_t del_idx = 0;
2527 uint8_t empty_slots = 0;
2528 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2529
2530 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2531 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2532 pHddStaCtx->conn_info.staId[idx] = 0;
2533
Anurag Chouhanc5548422016-02-24 18:33:27 +05302534 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002535 peerMacAddress[idx]);
2536
2537 fSuccess = true;
2538
2539 /*
2540 * Note the deleted Index, if its 0 we need special
2541 * handling.
2542 */
2543 del_idx = idx;
2544
2545 empty_slots++;
2546 } else {
2547 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2548 valid_idx = idx;
2549 } else {
2550 /* Found an empty slot */
2551 empty_slots++;
2552 }
2553 }
2554 }
2555
2556 if (MAX_IBSS_PEERS == empty_slots) {
2557 /* Last peer departed, set the IBSS state appropriately */
2558 pHddStaCtx->conn_info.connState =
2559 eConnectionState_IbssDisconnected;
2560 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2561 }
2562 /* Find next active staId, to have a valid sta trigger for TL. */
2563 if (fSuccess == true) {
2564 if (del_idx == 0) {
2565 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2566 pHddStaCtx->conn_info.staId[0] =
2567 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302568 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002569 peerMacAddress[0],
2570 &pHddStaCtx->conn_info.
2571 peerMacAddress[valid_idx]);
2572
2573 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302574 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002575 peerMacAddress[valid_idx]);
2576 }
2577 }
2578 }
2579 return fSuccess;
2580}
2581
2582/**
2583 * roam_ibss_connect_handler() - IBSS connection handler
2584 * @pAdapter: pointer to adapter
2585 * @pRoamInfo: pointer to roam info
2586 *
2587 * We update the status of the IBSS to connected in this function.
2588 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302589 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002590 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302591static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002592 tCsrRoamInfo *pRoamInfo)
2593{
2594 struct cfg80211_bss *bss;
2595 hddLog(LOG1, FL("IBSS Connect Indication from SME. Set HDD connState to eConnectionState_IbssConnected"));
2596 /*
2597 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2598 * a partner stations).
2599 */
2600 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2601
2602 /* Save the connection info from CSR... */
2603 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2604
2605 /* Send the bssid address to the wext. */
2606 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2607 /* add bss_id to cfg80211 data base */
2608 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2609 if (NULL == bss) {
2610 hddLog(LOGE,
2611 FL("%s: unable to create IBSS entry"),
2612 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302613 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614 }
2615 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002617 bss);
2618
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302619 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002620}
2621
2622/**
2623 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2624 * @pAdapter: pointer to adapter
2625 * @pRoamInfo: pointer to roam info
2626 * @roamId: roam id
2627 * @roamStatus: roam status
2628 * @roamResult: roam result
2629 *
2630 * This function indicates the Mic failure to the supplicant
2631 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302632 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002633 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302634static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002635hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2636 tCsrRoamInfo *pRoamInfo,
2637 uint32_t roamId,
2638 eRoamCmdStatus roamStatus,
2639 eCsrRoamResult roamResult)
2640{
2641 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2642
2643 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2644 TKIP_COUNTER_MEASURE_STOPED ==
2645 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2646 struct iw_michaelmicfailure msg;
2647 union iwreq_data wreq;
2648 memset(&msg, '\0', sizeof(msg));
2649 msg.src_addr.sa_family = ARPHRD_ETHER;
2650 memcpy(msg.src_addr.sa_data,
2651 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2652 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2653 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2654 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2655
2656 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2657 msg.flags = IW_MICFAILURE_GROUP;
2658 else
2659 msg.flags = IW_MICFAILURE_PAIRWISE;
2660 memset(&wreq, 0, sizeof(wreq));
2661 wreq.data.length = sizeof(msg);
2662 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2663 (char *)&msg);
2664 /* inform mic failure to nl80211 */
2665 cfg80211_michael_mic_failure(pAdapter->dev,
2666 pRoamInfo->u.pMICFailureInfo->
2667 taMacAddr,
2668 ((pRoamInfo->u.pMICFailureInfo->
2669 multicast ==
2670 eSIR_TRUE) ?
2671 NL80211_KEYTYPE_GROUP :
2672 NL80211_KEYTYPE_PAIRWISE),
2673 pRoamInfo->u.pMICFailureInfo->
2674 keyId,
2675 pRoamInfo->u.pMICFailureInfo->TSC,
2676 GFP_KERNEL);
2677
2678 }
2679
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302680 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002681}
2682
2683/**
2684 * roam_roam_connect_status_update_handler() - IBSS connect status update
2685 * @pAdapter: pointer to adapter
2686 * @pRoamInfo: pointer to roam info
2687 * @roamId: roam id
2688 * @roamStatus: roam status
2689 * @roamResult: roam result
2690 *
2691 * The Ibss connection status is updated regularly here in this function.
2692 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302693 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302695static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2697 tCsrRoamInfo *pRoamInfo,
2698 uint32_t roamId,
2699 eRoamCmdStatus roamStatus,
2700 eCsrRoamResult roamResult)
2701{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302702 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002703
2704 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2705 switch (roamResult) {
2706 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2707 {
2708 hdd_station_ctx_t *pHddStaCtx =
2709 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2710 struct station_info staInfo;
2711
2712 pr_info("IBSS New Peer indication from SME "
2713 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2714 MAC_ADDRESS_STR " and stationID= %d",
2715 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2716 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2717 pRoamInfo->staId);
2718
2719 if (!roam_save_ibss_station
2720 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2721 pRoamInfo->staId,
2722 &pRoamInfo->peerMac)) {
2723 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2724 break;
2725 }
2726
2727 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2728
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302730 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002731 pRoamInfo,
2732 pRoamInfo->staId,
2733 &pRoamInfo->peerMac,
2734 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302735 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002736 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302737 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2738 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002739 }
2740 pHddStaCtx->ibss_sta_generation++;
2741 memset(&staInfo, 0, sizeof(staInfo));
2742 staInfo.filled = 0;
2743 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2744
2745 cfg80211_new_sta(pAdapter->dev,
2746 (const u8 *)pRoamInfo->peerMac.bytes,
2747 &staInfo, GFP_KERNEL);
2748
2749 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2750 pHddStaCtx->ibss_enc_key.encType
2751 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2752 pHddStaCtx->ibss_enc_key.encType
2753 || eCSR_ENCRYPT_TYPE_TKIP ==
2754 pHddStaCtx->ibss_enc_key.encType
2755 || eCSR_ENCRYPT_TYPE_AES ==
2756 pHddStaCtx->ibss_enc_key.encType) {
2757 pHddStaCtx->ibss_enc_key.keyDirection =
2758 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302759 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002760 &pRoamInfo->peerMac);
2761
2762 hddLog(LOG2, "New peer joined set PTK encType=%d",
2763 pHddStaCtx->ibss_enc_key.encType);
2764
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302765 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002766 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2767 (pAdapter),
2768 pAdapter->sessionId,
2769 &pHddStaCtx->ibss_enc_key,
2770 &roamId);
2771
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302772 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002773 hddLog(LOGE,
2774 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302775 qdf_status);
2776 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002777 }
2778 }
2779 hddLog(LOG1, FL("Enabling queues"));
2780 wlan_hdd_netif_queue_control(pAdapter,
2781 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2782 WLAN_CONTROL_PATH);
2783 break;
2784 }
2785
2786 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2787 {
2788
2789 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2790
2791 break;
2792 }
2793 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2794 {
2795 hdd_station_ctx_t *pHddStaCtx =
2796 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2797
2798 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2799 hddLog(LOGW,
2800 "IBSS peer departed by cannot find peer in our registration table with TL");
2801
2802 pr_info("IBSS Peer Departed from SME "
2803 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2804 MAC_ADDRESS_STR " and stationID= %d",
2805 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2806 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2807 pRoamInfo->staId);
2808
2809 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2810
2811 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2812 pHddStaCtx->ibss_sta_generation++;
2813
2814 cfg80211_del_sta(pAdapter->dev,
2815 (const u8 *)&pRoamInfo->peerMac.bytes,
2816 GFP_KERNEL);
2817 break;
2818 }
2819 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2820 {
2821 hddLog(LOG3,
2822 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2823 /* Stop only when we are inactive */
2824 hddLog(LOG1, FL("Disabling queues"));
2825 wlan_hdd_netif_queue_control(pAdapter,
2826 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2827 WLAN_CONTROL_PATH);
2828 hddLog(LOG1,
2829 FL("Set HDD connState to eConnectionState_NotConnected"));
2830 hdd_conn_set_connection_state(pAdapter,
2831 eConnectionState_NotConnected);
2832
2833 /* Send the bssid address to the wext. */
2834 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2835 break;
2836 }
2837 default:
2838 break;
2839
2840 }
2841
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302842 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002843}
2844
2845#ifdef FEATURE_WLAN_TDLS
2846/**
2847 * hdd_roam_register_tdlssta() - register new TDLS station
2848 * @pAdapter: pointer to adapter
2849 * @peerMac: pointer to peer MAC address
2850 * @staId: station identifier
2851 * @ucastSig: unicast signature
2852 *
2853 * Construct the staDesc and register with TL the new STA.
2854 * This is called as part of ADD_STA in the TDLS setup.
2855 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302856 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002857 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302858QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002859 const uint8_t *peerMac, uint16_t staId,
2860 uint8_t ucastSig)
2861{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302862 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002863 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002864 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002865
2866 /*
2867 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2868 * be peer MAC, here we are working on direct Link
2869 */
2870 staDesc.sta_id = staId;
2871
2872 /* set the QoS field appropriately .. */
2873 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2874 : (staDesc.is_qos_enabled = 0);
2875
Dhanashri Atre50141c52016-04-07 13:15:29 -07002876 /* Register the vdev transmit and receive functions */
2877 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2878 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2879 ol_txrx_vdev_register(
2880 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2881 pAdapter, &txrx_ops);
2882 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002883
2884 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002885 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302886 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002887 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302888 qdf_status, qdf_status);
2889 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002890 }
2891
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302892 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002893}
2894
2895/**
2896 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2897 * @pAdapter: pointer to adapter
2898 * @staId: station identifier
2899 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302900 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002901 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302902static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002903 uint8_t staId)
2904{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302905 QDF_STATUS qdf_status;
2906 qdf_status = ol_txrx_clear_peer(staId);
2907 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002908 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302909 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002910 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302911 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002912}
2913
2914/**
2915 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2916 * @pAdapter: pointer to adapter
2917 * @pRoamInfo: pointer to roam info
2918 * @roamId: roam id
2919 * @roamStatus: roam status
2920 * @roamResult: roam result
2921 *
2922 * HDD interface between SME and TL to ensure TDLS client registration with
2923 * TL in case of new TDLS client is added and deregistration at the time
2924 * TDLS client is deleted.
2925 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302926 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002927 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302928static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002929hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
2930 tCsrRoamInfo *pRoamInfo,
2931 uint32_t roamId,
2932 eRoamCmdStatus roamStatus,
2933 eCsrRoamResult roamResult)
2934{
2935 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2936 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2937 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302938 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002939 uint8_t staIdx;
2940 hddTdlsPeer_t *curr_peer;
2941 uint32_t reason;
2942
2943 hddLog(LOG2,
2944 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
2945 roamResult ==
2946 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
2947 ==
2948 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
2949 roamResult ==
2950 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
2951 : roamResult ==
2952 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
2953 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
2954 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
2955 roamResult ==
2956 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
2957 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
2958 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
2959 : roamResult ==
2960 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
2961 : roamResult ==
2962 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
2963 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
2964 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
2965
2966 if (!pHddTdlsCtx) {
2967 hddLog(LOG1,
2968 FL("TDLS ctx is null, ignore roamResult (%d)"),
2969 roamResult);
2970 return status;
2971 }
2972
2973 switch (roamResult) {
2974 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
2975 {
2976 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
2977 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
2978 pRoamInfo->statusCode);
2979 } else {
2980 /*
2981 * Check if there is available index for this new TDLS
2982 * STA.
2983 */
2984 for (staIdx = 0;
2985 staIdx < pHddCtx->max_num_tdls_sta;
2986 staIdx++) {
2987 if (0 ==
2988 pHddCtx->tdlsConnInfo[staIdx].
2989 staId) {
2990 pHddCtx->tdlsConnInfo[staIdx].
2991 sessionId =
2992 pRoamInfo->sessionId;
2993 pHddCtx->tdlsConnInfo[staIdx].
2994 staId = pRoamInfo->staId;
2995
2996 hddLog(LOGW,
2997 ("TDLS: STA IDX at %d is %d "
2998 "of mac "
2999 MAC_ADDRESS_STR),
3000 staIdx,
3001 pHddCtx->
3002 tdlsConnInfo[staIdx].
3003 staId,
3004 MAC_ADDR_ARRAY
3005 (pRoamInfo->peerMac.bytes));
3006
Anurag Chouhanc5548422016-02-24 18:33:27 +05303007 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003008 tdlsConnInfo
3009 [staIdx].
3010 peerMac,
3011 &pRoamInfo->
3012 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303013 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003014 break;
3015 }
3016 }
3017 if (staIdx < pHddCtx->max_num_tdls_sta) {
3018 if (-1 ==
3019 wlan_hdd_tdls_set_sta_id(pAdapter,
3020 pRoamInfo->
3021 peerMac.bytes,
3022 pRoamInfo->
3023 staId)) {
3024 hddLog(LOGE,
3025 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303026 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003027 }
3028
3029 (WLAN_HDD_GET_CTX(pAdapter))->
3030 sta_to_adapter[pRoamInfo->staId] =
3031 pAdapter;
3032 /*
3033 * store the ucast signature,
3034 * if required for further reference.
3035 */
3036
3037 wlan_hdd_tdls_set_signature(pAdapter,
3038 pRoamInfo->
3039 peerMac.bytes,
3040 pRoamInfo->
3041 ucastSig);
3042 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303043 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003044 hddLog(LOGE,
3045 FL("no available slot in conn_info. staId %d cannot be stored"),
3046 pRoamInfo->staId);
3047 }
3048 pAdapter->tdlsAddStaStatus = status;
3049 }
3050 complete(&pAdapter->tdls_add_station_comp);
3051 break;
3052 }
3053 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3054 {
3055 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3056 hddLog(LOGE,
3057 FL("Add Sta failed. status code(=%d)"),
3058 pRoamInfo->statusCode);
3059 }
3060 /* store the ucast signature which will be used later when
3061 * registering to TL
3062 */
3063 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3064 complete(&pAdapter->tdls_add_station_comp);
3065 break;
3066 }
3067 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3068 {
3069 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3070 hddLog(LOGE,
3071 FL("Link Establish Request failed. status(=%d)"),
3072 pRoamInfo->statusCode);
3073 }
3074 complete(&pAdapter->tdls_link_establish_req_comp);
3075 break;
3076 }
3077 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3078 {
3079 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3080 staIdx++) {
3081 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3082 pRoamInfo->sessionId)
3083 && pRoamInfo->staId ==
3084 pHddCtx->tdlsConnInfo[staIdx].staId) {
3085 hddLog(LOGW,
3086 ("HDD: del STA IDX = %x"),
3087 pRoamInfo->staId);
3088
3089 curr_peer =
3090 wlan_hdd_tdls_find_peer(pAdapter,
3091 pRoamInfo->
3092 peerMac.bytes,
3093 true);
3094 if (NULL != curr_peer
3095 && TDLS_IS_CONNECTED(curr_peer)) {
3096 hdd_roam_deregister_tdlssta
3097 (pAdapter,
3098 pRoamInfo->staId);
3099 wlan_hdd_tdls_decrement_peer_count
3100 (pAdapter);
3101 }
3102 wlan_hdd_tdls_reset_peer(pAdapter,
3103 pRoamInfo->
3104 peerMac.bytes);
3105
3106 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3107 pHddCtx->tdlsConnInfo[staIdx].
3108 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303109 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003110 tdlsConnInfo[staIdx].
3111 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303112 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303113 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003114 break;
3115 }
3116 }
3117 complete(&pAdapter->tdls_del_station_comp);
3118 }
3119 break;
3120 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3121 {
3122 hddLog(LOGE,
3123 FL("Sending teardown to supplicant with reason code %u"),
3124 pRoamInfo->reasonCode);
3125
3126 curr_peer =
3127 wlan_hdd_tdls_find_peer(pAdapter,
3128 pRoamInfo->peerMac.bytes, true);
3129 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3130 pRoamInfo->reasonCode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303131 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003132 break;
3133 }
3134 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3135 {
3136 /* 0 staIdx is assigned to AP we dont want to touch that */
3137 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3138 staIdx++) {
3139 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3140 pRoamInfo->sessionId)
3141 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3142 hddLog(LOGW,
3143 ("hdd_tdlsStatusUpdate: staIdx %d "
3144 MAC_ADDRESS_STR),
3145 pHddCtx->tdlsConnInfo[staIdx].
3146 staId,
3147 MAC_ADDR_ARRAY(pHddCtx->
3148 tdlsConnInfo
3149 [staIdx].
3150 peerMac.
3151 bytes));
3152 wlan_hdd_tdls_reset_peer(pAdapter,
3153 pHddCtx->
3154 tdlsConnInfo
3155 [staIdx].
3156 peerMac.bytes);
3157 hdd_roam_deregister_tdlssta(pAdapter,
3158 pHddCtx->
3159 tdlsConnInfo
3160 [staIdx].
3161 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303162 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003163 sizeof
3164 (smeTdlsPeerStateParams));
3165 smeTdlsPeerStateParams.vdevId =
3166 pHddCtx->tdlsConnInfo[staIdx].
3167 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303168 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003169 peerMacAddr,
3170 &pHddCtx->
3171 tdlsConnInfo[staIdx].
3172 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303173 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003174 smeTdlsPeerStateParams.peerState =
3175 eSME_TDLS_PEER_STATE_TEARDOWN;
3176
3177 hddLog(LOG1,
3178 FL("calling sme_update_tdls_peer_state for staIdx %d "
3179 MAC_ADDRESS_STR),
3180 pHddCtx->tdlsConnInfo[staIdx].
3181 staId,
3182 MAC_ADDR_ARRAY(pHddCtx->
3183 tdlsConnInfo
3184 [staIdx].
3185 peerMac.
3186 bytes));
3187 status =
3188 sme_update_tdls_peer_state(
3189 pHddCtx->hHal,
3190 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303191 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003192 hddLog(LOGE,
3193 FL("sme_update_tdls_peer_state failed for "
3194 MAC_ADDRESS_STR),
3195 MAC_ADDR_ARRAY
3196 (pHddCtx->
3197 tdlsConnInfo[staIdx].
3198 peerMac.bytes));
3199 }
3200 wlan_hdd_tdls_decrement_peer_count
3201 (pAdapter);
3202
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303203 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003204 tdlsConnInfo[staIdx].
3205 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303206 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003207 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3208 pHddCtx->tdlsConnInfo[staIdx].
3209 sessionId = 255;
3210
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303211 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003212 }
3213 }
3214 break;
3215 }
3216 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3217 {
3218 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303219 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3220 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003221 hddLog(LOG2,
3222 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3223 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303224 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303225 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003226 break;
3227 }
3228
3229 curr_peer =
3230 wlan_hdd_tdls_get_peer(pAdapter,
3231 pRoamInfo->peerMac.bytes);
3232 if (!curr_peer) {
3233 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303234 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003235 } else {
3236 if (eTDLS_LINK_CONNECTED ==
3237 curr_peer->link_status) {
3238 hddLog(LOGE,
3239 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3240 } else {
3241 /*
3242 * If external control is enabled then initiate
3243 * TDLS only if forced peer is set otherwise
3244 * ignore should Discover trigger from fw.
3245 */
3246 if (pHddCtx->config->
3247 fTDLSExternalControl
3248 && (false ==
3249 curr_peer->isForcedPeer)) {
3250 hddLog(LOG2,
3251 FL
3252 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303253 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003254 break;
3255 } else {
3256 hddLog(LOG2,
3257 FL
3258 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3259 pHddCtx->config->
3260 fTDLSExternalControl,
3261 curr_peer->isForcedPeer,
3262 pRoamInfo->reasonCode);
3263 }
3264 wlan_hdd_tdls_pre_setup_init_work
3265 (pHddTdlsCtx, curr_peer);
3266 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303267 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003268 }
3269 break;
3270 }
3271
3272 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3273 {
3274 curr_peer =
3275 wlan_hdd_tdls_find_peer(pAdapter,
3276 pRoamInfo->peerMac.bytes, true);
3277 if (!curr_peer) {
3278 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303279 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003280 } else {
3281 if (eTDLS_LINK_CONNECTED ==
3282 curr_peer->link_status) {
3283 hddLog(LOGE,
3284 FL
3285 ("Received SHOULD_TEARDOWN for peer "
3286 MAC_ADDRESS_STR
3287 " staId: %d, reason: %d"),
3288 MAC_ADDR_ARRAY(pRoamInfo->
3289 peerMac.bytes),
3290 pRoamInfo->staId,
3291 pRoamInfo->reasonCode);
3292
3293 if (pRoamInfo->reasonCode ==
3294 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3295 pRoamInfo->reasonCode ==
3296 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3297 pRoamInfo->reasonCode ==
3298 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3299 pRoamInfo->reasonCode ==
3300 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3301 reason =
3302 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3303 } else
3304 reason =
3305 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3306
3307 wlan_hdd_tdls_indicate_teardown
3308 (pHddTdlsCtx->pAdapter, curr_peer,
3309 reason);
3310 } else {
3311 hddLog(LOGE,
3312 FL
3313 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3314 pRoamInfo->reasonCode);
3315 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303316 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003317 }
3318 break;
3319 }
3320
3321 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3322 {
3323 curr_peer =
3324 wlan_hdd_tdls_find_peer(pAdapter,
3325 pRoamInfo->peerMac.bytes, true);
3326 if (!curr_peer) {
3327 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303328 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003329 } else {
3330 if (eTDLS_LINK_CONNECTED ==
3331 curr_peer->link_status) {
3332 hddLog(LOGE,
3333 FL
3334 ("Received SHOULD_PEER_DISCONNECTED for peer "
3335 MAC_ADDRESS_STR
3336 " staId: %d, reason: %d"),
3337 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3338 pRoamInfo->staId,
3339 pRoamInfo->reasonCode);
3340
3341 if (pRoamInfo->reasonCode ==
3342 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3343 pRoamInfo->reasonCode ==
3344 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3345 pRoamInfo->reasonCode ==
3346 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3347 pRoamInfo->reasonCode ==
3348 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3349 reason =
3350 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3351 } else
3352 reason =
3353 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3354
3355 wlan_hdd_tdls_indicate_teardown
3356 (pHddTdlsCtx->pAdapter, curr_peer,
3357 reason);
3358 } else {
3359 hddLog(LOGE,
3360 FL
3361 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3362 pRoamInfo->reasonCode);
3363 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303364 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003365 }
3366 break;
3367 }
3368 default:
3369 {
3370 break;
3371 }
3372 }
3373
3374 return status;
3375}
3376#endif
3377
3378#ifdef WLAN_FEATURE_11W
3379/**
3380 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3381 * @pAdapter: pointer to the adapter
3382 * @nFrameLength: Length of the unprotected frame being passed
3383 * @pbFrames: Pointer to the frame buffer
3384 * @frameType: 802.11 frame type
3385 *
3386 * This function forwards the unprotected management frame to the supplicant.
3387 *
3388 * Return: nothing
3389 */
3390static void
3391hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3392 uint8_t *pbFrames, uint8_t frameType)
3393{
3394 uint8_t type = 0;
3395 uint8_t subType = 0;
3396
3397 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3398 frameType, nFrameLength);
3399
3400 /* Sanity Checks */
3401 if (NULL == pAdapter) {
3402 hddLog(LOGE, FL("pAdapter is NULL"));
3403 return;
3404 }
3405
3406 if (NULL == pAdapter->dev) {
3407 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3408 return;
3409 }
3410
3411 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3412 hddLog(LOGE, FL("pAdapter has invalid magic"));
3413 return;
3414 }
3415
3416 if (!nFrameLength) {
3417 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3418 return;
3419 }
3420
3421 if (NULL == pbFrames) {
3422 hddLog(LOGE, FL("pbFrames is NULL"));
3423 return;
3424 }
3425
3426 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3427 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3428
3429 /* Get pAdapter from Destination mac address of the frame */
3430 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3432 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3433 nFrameLength);
3434#else
3435 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3436 nFrameLength);
3437#endif
3438 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3439 } else if (type == SIR_MAC_MGMT_FRAME &&
3440 subType == SIR_MAC_MGMT_DEAUTH) {
3441#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3442 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3443 nFrameLength);
3444#else
3445 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3446 nFrameLength);
3447#endif
3448 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3449 } else {
3450 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3451 type, subType);
3452 return;
3453 }
3454}
3455#endif
3456
3457#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
3458/**
3459 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3460 * @pAdapter: pointer to adapter
3461 * @tid: traffic identifier
3462 * @state: state
3463 * @measInterval: measurement interval
3464 *
3465 * This function sends traffic stream metrics IE information to
3466 * the supplicant via wireless event.
3467 *
3468 * Return: none
3469 */
3470static void
3471hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3472 uint8_t state, uint16_t measInterval)
3473{
3474 union iwreq_data wrqu;
3475 char buf[IW_CUSTOM_MAX + 1];
3476 int nBytes = 0;
3477
3478 if (NULL == pAdapter)
3479 return;
3480
3481 /* create the event */
3482 memset(&wrqu, '\0', sizeof(wrqu));
3483 memset(buf, '\0', sizeof(buf));
3484
3485 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3486 tid, state, measInterval);
3487
3488 nBytes =
3489 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3490 measInterval);
3491
3492 wrqu.data.pointer = buf;
3493 wrqu.data.length = nBytes;
3494 /* send the event */
3495 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3496}
3497
3498/**
3499 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3500 * @pAdapter: pointer to adapter
3501 * @pRoamInfo: pointer to roam info
3502 *
3503 * This function sends cckm preauth indication to the supplicant
3504 * via wireless custom event.
3505 *
3506 * Return: none
3507 */
3508static void
3509hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3510{
3511 union iwreq_data wrqu;
3512 char buf[IW_CUSTOM_MAX + 1];
3513 char *pos = buf;
3514 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3515
3516 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3517 return;
3518
3519 /* create the event */
3520 memset(&wrqu, '\0', sizeof(wrqu));
3521 memset(buf, '\0', sizeof(buf));
3522
3523 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3524 hddLog(LOG1,
3525 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3526 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3527 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3528
3529 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3530 pos += nBytes;
3531 freeBytes -= nBytes;
3532
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303533 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303534 pos += QDF_MAC_ADDR_SIZE;
3535 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003536
3537 nBytes = snprintf(pos, freeBytes, " %u:%u",
3538 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3539 freeBytes -= nBytes;
3540
3541 wrqu.data.pointer = buf;
3542 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3543
3544 /* send the event */
3545 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3546}
3547
3548/**
3549 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3550 * @pAdapter: pointer to adapter
3551 * @pRoamInfo: pointer to roam info
3552 *
3553 * Return: none
3554 */
3555static void
3556hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3557 tCsrRoamInfo *pRoamInfo)
3558{
3559 union iwreq_data wrqu;
3560 char buf[IW_CUSTOM_MAX + 1];
3561 int nBytes = 0;
3562
3563 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3564 return;
3565
3566 /* create the event */
3567 memset(&wrqu, '\0', sizeof(wrqu));
3568 memset(buf, '\0', sizeof(buf));
3569
3570 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3571
3572 nBytes =
3573 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3574 pRoamInfo->tsmRoamDelay);
3575
3576 wrqu.data.pointer = buf;
3577 wrqu.data.length = nBytes;
3578
3579 /* send the event */
3580 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3581}
3582
3583/**
3584 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3585 * @pAdapter: pointer to adapter
3586 * @measurementToken: measurement token
3587 * @flag: flag
3588 * @numBss: number of bss
3589 *
3590 * If the measurement is none and no scan results found,
3591 * indicate the supplicant about measurement done.
3592 *
3593 * Return: none
3594 */
3595void
3596hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3597 const uint16_t measurementToken,
3598 const bool flag, const uint8_t numBss)
3599{
3600 union iwreq_data wrqu;
3601 char buf[IW_CUSTOM_MAX];
3602 char *pos = buf;
3603 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3604
3605 memset(&wrqu, '\0', sizeof(wrqu));
3606 memset(buf, '\0', sizeof(buf));
3607
3608 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3609 flag, numBss);
3610
3611 nBytes =
3612 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3613 flag, numBss);
3614
3615 wrqu.data.pointer = buf;
3616 wrqu.data.length = nBytes;
3617 /* send the event */
3618 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3619}
3620
3621/**
3622 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3623 * @pAdapter: pointer to adapter
3624 * @pRoamInfo: pointer to roam info
3625 *
3626 * If the measurement is none and no scan results found,
3627 * indicate the supplicant about measurement done.
3628 *
3629 * Return: none
3630 */
3631static void
3632hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3633 const tCsrRoamInfo *pRoamInfo)
3634{
3635 union iwreq_data wrqu;
3636 char buf[IW_CUSTOM_MAX];
3637 char *pos = buf;
3638 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3639 uint8_t i = 0, len = 0;
3640 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3641 uint8_t lastSent = 0, sendBss = 0;
3642 int bcnRepFieldSize =
3643 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3644 bcnReportFields);
3645 uint8_t ieLenByte = 1;
3646 /*
3647 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3648 */
3649#define ESEBCNREPHEADER_LEN (18)
3650
3651 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3652 return;
3653
3654 /*
3655 * Custom event can pass maximum of 256 bytes of data,
3656 * based on the IE len we need to identify how many BSS info can
3657 * be filled in to custom event data.
3658 */
3659 /*
3660 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3661 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3662 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3663 */
3664
3665 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3666 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3667 hddLog(LOG1,
3668 "Measurement Done but no scan results");
3669 /* If the measurement is none and no scan results found,
3670 indicate the supplicant about measurement done */
3671 hdd_indicate_ese_bcn_report_no_results(
3672 pAdapter,
3673 pRoamInfo->pEseBcnReportRsp->
3674 measurementToken,
3675 pRoamInfo->pEseBcnReportRsp->flag,
3676 pRoamInfo->pEseBcnReportRsp->numBss);
3677 } else {
3678 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3679 memset(&wrqu, '\0', sizeof(wrqu));
3680 memset(buf, '\0', sizeof(buf));
3681 tot_bcn_ieLen = 0;
3682 sendBss = 0;
3683 pos = buf;
3684 freeBytes = IW_CUSTOM_MAX;
3685
3686 for (i = lastSent;
3687 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3688 len =
3689 bcnRepFieldSize + ieLenByte +
3690 pRoamInfo->pEseBcnReportRsp->
3691 bcnRepBssInfo[i].ieLen;
3692 if ((len + tot_bcn_ieLen) >
3693 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3694 break;
3695 }
3696 tot_bcn_ieLen += len;
3697 sendBss++;
3698 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3699 i, bcnRepFieldSize, 1,
3700 pRoamInfo->pEseBcnReportRsp->
3701 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3702 }
3703
3704 hddLog(LOG1, "Sending %d BSS Info",
3705 sendBss);
3706 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3707 pRoamInfo->pEseBcnReportRsp->measurementToken,
3708 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3709 tot_bcn_ieLen);
3710
3711 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3712 pRoamInfo->pEseBcnReportRsp->
3713 measurementToken,
3714 pRoamInfo->pEseBcnReportRsp->flag,
3715 sendBss);
3716 pos += nBytes;
3717 freeBytes -= nBytes;
3718
3719 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303720 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003721 sizeof(tot_bcn_ieLen));
3722 pos += sizeof(tot_bcn_ieLen);
3723 freeBytes -= sizeof(tot_bcn_ieLen);
3724
3725 for (i = 0; i < sendBss; i++) {
3726 hddLog(LOG1,
3727 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3728 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3729 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3730 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3731 pRoamInfo->pEseBcnReportRsp->
3732 bcnRepBssInfo[i +
3733 lastSent].bcnReportFields.
3734 ChanNum,
3735 pRoamInfo->pEseBcnReportRsp->
3736 bcnRepBssInfo[i +
3737 lastSent].bcnReportFields.
3738 Spare,
3739 pRoamInfo->pEseBcnReportRsp->
3740 bcnRepBssInfo[i +
3741 lastSent].bcnReportFields.
3742 MeasDuration,
3743 pRoamInfo->pEseBcnReportRsp->
3744 bcnRepBssInfo[i +
3745 lastSent].bcnReportFields.
3746 PhyType,
3747 pRoamInfo->pEseBcnReportRsp->
3748 bcnRepBssInfo[i +
3749 lastSent].bcnReportFields.
3750 RecvSigPower,
3751 pRoamInfo->pEseBcnReportRsp->
3752 bcnRepBssInfo[i +
3753 lastSent].bcnReportFields.
3754 ParentTsf,
3755 pRoamInfo->pEseBcnReportRsp->
3756 bcnRepBssInfo[i +
3757 lastSent].bcnReportFields.
3758 TargetTsf[0],
3759 pRoamInfo->pEseBcnReportRsp->
3760 bcnRepBssInfo[i +
3761 lastSent].bcnReportFields.
3762 TargetTsf[1],
3763 pRoamInfo->pEseBcnReportRsp->
3764 bcnRepBssInfo[i +
3765 lastSent].bcnReportFields.
3766 BcnInterval,
3767 pRoamInfo->pEseBcnReportRsp->
3768 bcnRepBssInfo[i +
3769 lastSent].bcnReportFields.
3770 CapabilityInfo,
3771 pRoamInfo->pEseBcnReportRsp->
3772 bcnRepBssInfo[i +
3773 lastSent].bcnReportFields.
3774 Bssid[0],
3775 pRoamInfo->pEseBcnReportRsp->
3776 bcnRepBssInfo[i +
3777 lastSent].bcnReportFields.
3778 Bssid[1],
3779 pRoamInfo->pEseBcnReportRsp->
3780 bcnRepBssInfo[i +
3781 lastSent].bcnReportFields.
3782 Bssid[2],
3783 pRoamInfo->pEseBcnReportRsp->
3784 bcnRepBssInfo[i +
3785 lastSent].bcnReportFields.
3786 Bssid[3],
3787 pRoamInfo->pEseBcnReportRsp->
3788 bcnRepBssInfo[i +
3789 lastSent].bcnReportFields.
3790 Bssid[4],
3791 pRoamInfo->pEseBcnReportRsp->
3792 bcnRepBssInfo[i +
3793 lastSent].bcnReportFields.
3794 Bssid[5]);
3795
3796 /* bcn report fields are copied */
3797 len =
3798 sizeof(pRoamInfo->pEseBcnReportRsp->
3799 bcnRepBssInfo[i +
3800 lastSent].
3801 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303802 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003803 (char *)&pRoamInfo->
3804 pEseBcnReportRsp->bcnRepBssInfo[i +
3805 lastSent].
3806 bcnReportFields, len);
3807 pos += len;
3808 freeBytes -= len;
3809
3810 /* Add 1 byte of ie len */
3811 len =
3812 pRoamInfo->pEseBcnReportRsp->
3813 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303814 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003815 pos += sizeof(len);
3816 freeBytes -= sizeof(len);
3817
3818 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303819 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003820 (char *)pRoamInfo->
3821 pEseBcnReportRsp->bcnRepBssInfo[i +
3822 lastSent].
3823 pBuf, len);
3824 pos += len;
3825 freeBytes -= len;
3826 }
3827
3828 wrqu.data.pointer = buf;
3829 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3830
3831 /* send the event */
3832 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3833 buf);
3834 lastSent += sendBss;
3835 }
3836 }
3837}
3838
3839#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
3840
3841/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303842 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
3843 * @pHddStaCtx: Station Context
3844 *
3845 * API to check if the connection authentication type is 8021x_sha256.
3846 *
3847 * Return: bool
3848 */
3849#ifdef WLAN_FEATURE_11W
3850static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3851{
3852 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
3853 pHddStaCtx->conn_info.authType;
3854}
3855#else
3856static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3857{
3858 return false;
3859}
3860#endif
3861
3862/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003863 * hdd_sme_roam_callback() - hdd sme roam callback
3864 * @pContext: pointer to adapter context
3865 * @pRoamInfo: pointer to roam info
3866 * @roamId: roam id
3867 * @roamStatus: roam status
3868 * @roamResult: roam result
3869 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303870 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003871 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303872QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3874 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3875{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303876 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003877 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3878 hdd_wext_state_t *pWextState = NULL;
3879 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303880 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003881 hdd_context_t *pHddCtx = NULL;
3882
3883 hddLog(LOG2,
3884 "CSR Callback: status= %d result= %d roamID=%d",
3885 roamStatus, roamResult, roamId);
3886
3887 /* Sanity check */
3888 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3889 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303890 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003891 }
3892
3893 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3894 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3895
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303896 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05303897 pAdapter->sessionId, roamStatus));
3898
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003899 switch (roamStatus) {
3900 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05303901 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3902 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08003903 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003904 break;
3905
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003906 /*
3907 * We did pre-auth,then we attempted a 11r or ese reassoc.
3908 * reassoc failed due to failure, timeout, reject from ap
3909 * in any case tell the OS, our carrier is off and mark
3910 * interface down.
3911 */
3912 case eCSR_ROAM_FT_REASSOC_FAILED:
3913 hddLog(LOGE,
3914 FL
3915 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
3916 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303917 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003918 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3919 roamStatus, roamResult);
3920 /*
3921 * Check if Mcast/Bcast Filters are set, if yes
3922 * clear the filters here.
3923 */
3924 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
3925 true) {
3926 (WLAN_HDD_GET_CTX(pAdapter))->
3927 hdd_mcastbcast_filter_set = false;
3928 }
3929 pHddStaCtx->ft_carrier_on = false;
3930 pHddStaCtx->hdd_ReassocScenario = false;
3931 hddLog(LOG1,
3932 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
3933 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3934 break;
3935
3936 case eCSR_ROAM_FT_START:
3937 /*
3938 * When we roam for ESE and 11r, we dont want the OS to be
3939 * informed that the link is down. So mark the link ready for
3940 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
3941 * be received. Where in we will not mark the link down
3942 * Also we want to stop tx at this point when we will be
3943 * doing disassoc at this time. This saves 30-60 msec
3944 * after reassoc.
3945 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003946 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07003947 wlan_hdd_netif_queue_control(pAdapter,
3948 WLAN_NETIF_TX_DISABLE,
3949 WLAN_CONTROL_PATH);
3950 status = hdd_roam_deregister_sta(pAdapter,
3951 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303952 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303953 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003954 pHddStaCtx->ft_carrier_on = true;
3955 pHddStaCtx->hdd_ReassocScenario = true;
3956 hddLog(LOG1,
3957 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
3958 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3959 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003960
3961 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003962 /* notify apps that we can't pass traffic anymore */
3963 hddLog(LOG1, FL("Disabling queues"));
3964 wlan_hdd_netif_queue_control(pAdapter,
3965 WLAN_NETIF_TX_DISABLE,
3966 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003967 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003968 wlan_hdd_netif_queue_control(pAdapter,
3969 WLAN_NETIF_CARRIER_OFF,
3970 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003971 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003972 break;
3973 case eCSR_ROAM_LOSTLINK:
3974 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
3975 hddLog(LOG2, "Roaming started due to connection lost");
3976 hddLog(LOG1, FL("Disabling queues"));
3977 wlan_hdd_netif_queue_control(pAdapter,
3978 WLAN_NETIF_TX_DISABLE_N_CARRIER,
3979 WLAN_CONTROL_PATH);
3980 break;
3981 }
3982 case eCSR_ROAM_DISASSOCIATED:
3983 {
3984 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303985 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003986 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3987 roamStatus, roamResult);
3988 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
3989 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3990 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
3991 hdd_conf_mcastbcast_filter(pHddCtx, false);
3992
3993 if (true ==
3994 pHddCtx->sus_res_mcastbcast_filter_valid) {
3995 pHddCtx->configuredMcastBcastFilter =
3996 pHddCtx->sus_res_mcastbcast_filter;
3997 pHddCtx->
3998 sus_res_mcastbcast_filter_valid =
3999 false;
4000 }
4001
4002 hddLog(LOG1,
4003 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4004 hddLog(LOG1,
4005 "McastBcastFilter = %d",
4006 pHddCtx->configuredMcastBcastFilter);
4007 hddLog(LOG1,
4008 "offload: already called mcastbcast filter");
4009 (WLAN_HDD_GET_CTX(pAdapter))->
4010 hdd_mcastbcast_filter_set = false;
4011 }
4012 /* Call to clear any MC Addr List filter applied after
4013 * successful connection.
4014 */
4015 wlan_hdd_set_mc_addr_list(pAdapter, false);
4016 }
4017 break;
4018 case eCSR_ROAM_IBSS_LEAVE:
4019 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304020 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004021 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4022 roamStatus, roamResult);
4023 break;
4024 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4025 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4026 /*
4027 * To Do - address probable memory leak with WEP encryption upon
4028 * successful association.
4029 */
4030 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4031 /* Clear saved connection information in HDD */
4032 hdd_conn_remove_connect_info(
4033 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4034 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304035 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004036 hdd_association_completion_handler(pAdapter, pRoamInfo,
4037 roamId, roamStatus,
4038 roamResult);
4039#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4040 if (pRoamInfo)
4041 pRoamInfo->roamSynchInProgress = false;
4042#endif
4043 break;
4044 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304045 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004046 pRoamInfo,
4047 roamId,
4048 roamStatus,
4049 roamResult);
4050 break;
4051 case eCSR_ROAM_IBSS_IND:
4052 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4053 roamStatus, roamResult);
4054 break;
4055
4056 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304057 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004058 roam_roam_connect_status_update_handler(pAdapter,
4059 pRoamInfo,
4060 roamId,
4061 roamStatus,
4062 roamResult);
4063 break;
4064
4065 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304066 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004067 hdd_roam_mic_error_indication_handler(pAdapter,
4068 pRoamInfo,
4069 roamId,
4070 roamStatus,
4071 roamResult);
4072 break;
4073
4074 case eCSR_ROAM_SET_KEY_COMPLETE:
4075 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304076 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004077 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4078 roamId, roamStatus,
4079 roamResult);
4080 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4081 pHddStaCtx->hdd_ReassocScenario = false;
4082 hddLog(LOG1,
4083 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4084 pHddStaCtx->hdd_ReassocScenario,
4085 pAdapter->sessionId);
4086 }
4087 }
4088#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4089 if (pRoamInfo != NULL)
4090 pRoamInfo->roamSynchInProgress = false;
4091#endif
4092 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004093
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004094 case eCSR_ROAM_FT_RESPONSE:
4095 hdd_send_ft_event(pAdapter);
4096 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004097
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004098 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304099 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4100 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004101 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304102 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004103 wlan_hdd_cfg80211_pmksa_candidate_notify(
4104 pAdapter, pRoamInfo, 1, false);
4105 }
4106 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004107
4108#ifdef FEATURE_WLAN_LFR_METRICS
4109 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4110 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304111 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004112 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4113 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304114 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004115 }
4116 break;
4117 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4118 /*
4119 * This event will notify pre-auth completion in case of success
4120 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304121 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004122 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4123 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304124 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004125 }
4126 break;
4127 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4128 /*
4129 * This event will notify pre-auth completion incase of failure.
4130 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304131 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004132 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4133 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304134 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004135 }
4136 break;
4137 case eCSR_ROAM_HANDOVER_SUCCESS:
4138 /* This event is to notify handover success.
4139 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304140 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4142 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304143 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004144 }
4145 break;
4146#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004147 case eCSR_ROAM_REMAIN_CHAN_READY:
4148 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4149 break;
4150 case eCSR_ROAM_SEND_ACTION_CNF:
4151 hdd_send_action_cnf(pAdapter,
4152 (roamResult ==
4153 eCSR_ROAM_RESULT_NONE) ? true : false);
4154 break;
4155#ifdef FEATURE_WLAN_TDLS
4156 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304157 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004158 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4159 roamId,
4160 roamStatus,
4161 roamResult);
4162 break;
4163 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4164 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4165 pRoamInfo->reasonCode);
4166 break;
4167#endif
4168#ifdef WLAN_FEATURE_11W
4169 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4170 hdd_indicate_unprot_mgmt_frame(pAdapter,
4171 pRoamInfo->nFrameLength,
4172 pRoamInfo->pbFrames,
4173 pRoamInfo->frameType);
4174 break;
4175#endif
4176#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4177 case eCSR_ROAM_TSM_IE_IND:
4178 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4179 pRoamInfo->tsmIe.state,
4180 pRoamInfo->tsmIe.msmt_interval);
4181 break;
4182
4183 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4184 {
4185 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4186 pHddStaCtx->conn_info.authType
4187 || eCSR_AUTH_TYPE_CCKM_RSN ==
4188 pHddStaCtx->conn_info.authType) {
4189 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4190 }
4191 break;
4192 }
4193
4194 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4195 {
4196 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4197 break;
4198 }
4199
4200 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4201 {
4202 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4203 break;
4204 }
4205#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
4206 default:
4207 break;
4208 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304209 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004210}
4211
4212/**
4213 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4214 * @auth_suite: auth suite
4215 *
4216 * Return: eCsrAuthType enumeration
4217 */
4218eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4219{
4220 eCsrAuthType auth_type;
4221 /* is the auth type supported? */
4222 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4223 auth_type = eCSR_AUTH_TYPE_RSN;
4224 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4225 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004226 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004227 /* Check for 11r FT Authentication with PSK */
4228 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4229 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4230 /* Check for 11R FT Authentication with 802.1X */
4231 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4232 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004233#ifdef FEATURE_WLAN_ESE
4234 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4235 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4236 } else
4237#endif /* FEATURE_WLAN_ESE */
4238#ifdef WLAN_FEATURE_11W
4239 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4240 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4241 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4242 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4243 } else
4244#endif
4245 {
4246 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4247 }
4248 return auth_type;
4249}
4250
4251/**
4252 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4253 * @auth_suite: auth suite
4254 *
4255 * Return: eCsrAuthType enumeration
4256 */
4257eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4258{
4259 eCsrAuthType auth_type;
4260 /* is the auth type supported? */
4261 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4262 auth_type = eCSR_AUTH_TYPE_WPA;
4263 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4264 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4265 } else
4266#ifdef FEATURE_WLAN_ESE
4267 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4268 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4269 } else
4270#endif /* FEATURE_WLAN_ESE */
4271 {
4272 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4273 }
4274 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4275 return auth_type;
4276}
4277
4278/**
4279 * hdd_translate_rsn_to_csr_encryption_type() -
4280 * Translate RSN to CSR encryption type
4281 * @cipher_suite: cipher suite
4282 *
4283 * Return: eCsrEncryptionType enumeration
4284 */
4285eCsrEncryptionType
4286hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4287{
4288 eCsrEncryptionType cipher_type;
4289
4290 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4291 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4292 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4293 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4294 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4295 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4296 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4297 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4298 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4299 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4300 else
4301 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4302
4303 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4304 return cipher_type;
4305}
4306
4307/**
4308 * hdd_translate_wpa_to_csr_encryption_type() -
4309 * Translate WPA to CSR encryption type
4310 * @cipher_suite: cipher suite
4311 *
4312 * Return: eCsrEncryptionType enumeration
4313 */
4314eCsrEncryptionType
4315hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4316{
4317 eCsrEncryptionType cipher_type;
4318
4319 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4320 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4321 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4322 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4323 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4324 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4325 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4326 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4327 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4328 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4329 else
4330 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4331
4332 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4333 return cipher_type;
4334}
4335
4336/**
4337 * hdd_process_genie() - process gen ie
4338 * @pAdapter: pointer to adapter
4339 * @bssid: pointer to mac address
4340 * @pEncryptType: pointer to encryption type
4341 * @mcEncryptType: pointer to multicast encryption type
4342 * @pAuthType: pointer to auth type
4343 *
4344 * Return: 0 on success, error number otherwise
4345 */
4346static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4347 u8 *bssid,
4348 eCsrEncryptionType *pEncryptType,
4349 eCsrEncryptionType *mcEncryptType,
4350 eCsrAuthType *pAuthType,
4351#ifdef WLAN_FEATURE_11W
4352 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4353#endif
4354 uint16_t gen_ie_len, uint8_t *gen_ie)
4355{
4356 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304357 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004358 tDot11fIERSN dot11RSNIE;
4359 tDot11fIEWPA dot11WPAIE;
4360 uint32_t i;
4361 uint8_t *pRsnIe;
4362 uint16_t RSNIeLen;
4363 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4364 bool updatePMKCache = false;
4365
4366 /*
4367 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4368 * setting present flag to 0.
4369 */
4370 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4371 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4372
4373 /* Type check */
4374 if (gen_ie[0] == DOT11F_EID_RSN) {
4375 /* Validity checks */
4376 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4377 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4378 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4379 gen_ie_len);
4380 return -EINVAL;
4381 }
4382 /* Skip past the EID byte and length byte */
4383 pRsnIe = gen_ie + 2;
4384 RSNIeLen = gen_ie_len - 2;
4385 /* Unpack the RSN IE */
4386 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4387 pRsnIe, RSNIeLen, &dot11RSNIE);
4388 /* Copy out the encryption and authentication types */
4389 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4390 dot11RSNIE.pwise_cipher_suite_count);
4391 hddLog(LOG1, FL("authentication suite count: %d"),
4392 dot11RSNIE.akm_suite_count);
4393 /*Here we have followed the apple base code,
4394 but probably I suspect we can do something different */
4395 /* dot11RSNIE.akm_suite_count */
4396 /* Just translate the FIRST one */
4397 *pAuthType =
4398 hdd_translate_rsn_to_csr_auth_type(
4399 dot11RSNIE.akm_suites[0]);
4400 /* dot11RSNIE.pwise_cipher_suite_count */
4401 *pEncryptType =
4402 hdd_translate_rsn_to_csr_encryption_type(
4403 dot11RSNIE.pwise_cipher_suites[0]);
4404 /* dot11RSNIE.gp_cipher_suite_count */
4405 *mcEncryptType =
4406 hdd_translate_rsn_to_csr_encryption_type(
4407 dot11RSNIE.gp_cipher_suite);
4408#ifdef WLAN_FEATURE_11W
4409 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4410 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4411#endif
4412 /* Set the PMKSA ID Cache for this interface */
4413 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4414 if (is_zero_ether_addr(bssid)) {
4415 hddLog(LOGE, FL("MAC address is all zeroes"));
4416 break;
4417 }
4418 updatePMKCache = true;
4419 /*
4420 * For right now, I assume setASSOCIATE() has passed
4421 * in the bssid.
4422 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304423 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304424 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304425 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004426 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4427 }
4428
4429 if (updatePMKCache) {
4430 /*
4431 * Calling csr_roam_set_pmkid_cache to configure the
4432 * PMKIDs into the cache.
4433 */
4434 hddLog(LOG1,
4435 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4436 i);
4437 /* Finally set the PMKSA ID Cache in CSR */
4438 result =
4439 sme_roam_set_pmkid_cache(halHandle,
4440 pAdapter->sessionId,
4441 PMKIDCache,
4442 dot11RSNIE.pmkid_count,
4443 false);
4444 }
4445 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4446 /* Validity checks */
4447 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4448 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4449 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4450 gen_ie_len);
4451 return -EINVAL;
4452 }
4453 /* Skip past the EID and length byte - and four byte WiFi OUI */
4454 pRsnIe = gen_ie + 2 + 4;
4455 RSNIeLen = gen_ie_len - (2 + 4);
4456 /* Unpack the WPA IE */
4457 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4458 pRsnIe, RSNIeLen, &dot11WPAIE);
4459 /* Copy out the encryption and authentication types */
4460 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4461 dot11WPAIE.unicast_cipher_count);
4462 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4463 dot11WPAIE.auth_suite_count);
4464 /* dot11WPAIE.auth_suite_count */
4465 /* Just translate the FIRST one */
4466 *pAuthType =
4467 hdd_translate_wpa_to_csr_auth_type(
4468 dot11WPAIE.auth_suites[0]);
4469 /* dot11WPAIE.unicast_cipher_count */
4470 *pEncryptType =
4471 hdd_translate_wpa_to_csr_encryption_type(
4472 dot11WPAIE.unicast_ciphers[0]);
4473 /* dot11WPAIE.unicast_cipher_count */
4474 *mcEncryptType =
4475 hdd_translate_wpa_to_csr_encryption_type(
4476 dot11WPAIE.multicast_cipher);
4477 } else {
4478 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4479 return -EINVAL;
4480 }
4481 return 0;
4482}
4483
4484/**
4485 * hdd_set_genie_to_csr() - set genie to csr
4486 * @pAdapter: pointer to adapter
4487 * @RSNAuthType: pointer to auth type
4488 *
4489 * Return: 0 on success, error number otherwise
4490 */
4491int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4492{
4493 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4494 uint32_t status = 0;
4495 eCsrEncryptionType RSNEncryptType;
4496 eCsrEncryptionType mcRSNEncryptType;
4497#ifdef WLAN_FEATURE_11W
4498 uint8_t RSNMfpRequired = 0;
4499 uint8_t RSNMfpCapable = 0;
4500#endif
4501 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4502 /* MAC address of assoc peer */
4503 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304504 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004505 pWextState->roamProfile.BSSIDs.bssid,
4506 sizeof(bssid));
4507 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4508 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4509 /* continue */
4510 } else {
4511 return 0;
4512 }
4513 /* The actual processing may eventually be more extensive than this. */
4514 /* Right now, just consume any PMKIDs that are sent in by the app. */
4515 status = hdd_process_genie(pAdapter, bssid,
4516 &RSNEncryptType,
4517 &mcRSNEncryptType, RSNAuthType,
4518#ifdef WLAN_FEATURE_11W
4519 &RSNMfpRequired, &RSNMfpCapable,
4520#endif
4521 pWextState->WPARSNIE[1] + 2,
4522 pWextState->WPARSNIE);
4523 if (status == 0) {
4524 /*
4525 * Now copy over all the security attributes
4526 * you have parsed out.
4527 */
4528 pWextState->roamProfile.EncryptionType.numEntries = 1;
4529 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4530
4531 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4532 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4533 mcRSNEncryptType;
4534
4535 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
4536 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4537 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4538 /*
4539 * For wpa none supplicant sends the WPA IE with unicast
4540 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4541 * multicast cipher as either AES/TKIP based on group
4542 * cipher configuration mentioned in the
4543 * wpa_supplicant.conf.
4544 */
4545
4546 /* Set the unicast cipher same as multicast cipher */
4547 pWextState->roamProfile.EncryptionType.encryptionType[0]
4548 = mcRSNEncryptType;
4549 }
4550#ifdef WLAN_FEATURE_11W
4551 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4552 RSNMfpRequired, RSNMfpCapable);
4553 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4554 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4555#endif
4556 hddLog(LOG1,
4557 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4558 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4559 }
4560 return 0;
4561}
4562
4563/**
4564 * hdd_set_csr_auth_type() - set csr auth type
4565 * @pAdapter: pointer to adapter
4566 * @RSNAuthType: auth type
4567 *
4568 * Return: 0 on success, error number otherwise
4569 */
4570int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4571{
4572 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4573 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4574 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4575 ENTER();
4576
4577 pRoamProfile->AuthType.numEntries = 1;
4578 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4579 pHddStaCtx->conn_info.authType);
4580
4581 switch (pHddStaCtx->conn_info.authType) {
4582 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4583#ifdef FEATURE_WLAN_ESE
4584 case eCSR_AUTH_TYPE_CCKM_WPA:
4585 case eCSR_AUTH_TYPE_CCKM_RSN:
4586#endif
4587 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4588
4589 pRoamProfile->AuthType.authType[0] =
4590 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4591 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4592
4593#ifdef FEATURE_WLAN_ESE
4594 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4595 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4596 == IW_AUTH_KEY_MGMT_802_1X)) {
4597 hddLog(LOG1,
4598 FL("set authType to CCKM WPA. AKM also 802.1X."));
4599 pRoamProfile->AuthType.authType[0] =
4600 eCSR_AUTH_TYPE_CCKM_WPA;
4601 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4602 hddLog(LOG1,
4603 FL("Last chance to set authType to CCKM WPA."));
4604 pRoamProfile->AuthType.authType[0] =
4605 eCSR_AUTH_TYPE_CCKM_WPA;
4606 } else
4607#endif
4608 if ((pWextState->
4609 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4610 == IW_AUTH_KEY_MGMT_802_1X) {
4611 pRoamProfile->AuthType.authType[0] =
4612 eCSR_AUTH_TYPE_WPA;
4613 } else
4614 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4615 == IW_AUTH_KEY_MGMT_PSK) {
4616 pRoamProfile->AuthType.authType[0] =
4617 eCSR_AUTH_TYPE_WPA_PSK;
4618 } else {
4619 pRoamProfile->AuthType.authType[0] =
4620 eCSR_AUTH_TYPE_WPA_NONE;
4621 }
4622 }
4623 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4624#ifdef FEATURE_WLAN_ESE
4625 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4626 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4627 == IW_AUTH_KEY_MGMT_802_1X)) {
4628 hddLog(LOG1,
4629 FL("set authType to CCKM RSN. AKM also 802.1X."));
4630 pRoamProfile->AuthType.authType[0] =
4631 eCSR_AUTH_TYPE_CCKM_RSN;
4632 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4633 hddLog(LOG1,
4634 FL("Last chance to set authType to CCKM RSN."));
4635 pRoamProfile->AuthType.authType[0] =
4636 eCSR_AUTH_TYPE_CCKM_RSN;
4637 } else
4638#endif
4639
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004640 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4641 ((pWextState->
4642 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4643 == IW_AUTH_KEY_MGMT_802_1X)) {
4644 pRoamProfile->AuthType.authType[0] =
4645 eCSR_AUTH_TYPE_FT_RSN;
4646 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4647 &&
4648 ((pWextState->
4649 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4650 == IW_AUTH_KEY_MGMT_PSK)) {
4651 pRoamProfile->AuthType.authType[0] =
4652 eCSR_AUTH_TYPE_FT_RSN_PSK;
4653 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004654
4655#ifdef WLAN_FEATURE_11W
4656 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4657 pRoamProfile->AuthType.authType[0] =
4658 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4659 } else if (RSNAuthType ==
4660 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4661 pRoamProfile->AuthType.authType[0] =
4662 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4663 } else
4664#endif
4665
4666 if ((pWextState->
4667 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4668 == IW_AUTH_KEY_MGMT_802_1X) {
4669 pRoamProfile->AuthType.authType[0] =
4670 eCSR_AUTH_TYPE_RSN;
4671 } else
4672 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4673 == IW_AUTH_KEY_MGMT_PSK) {
4674 pRoamProfile->AuthType.authType[0] =
4675 eCSR_AUTH_TYPE_RSN_PSK;
4676 } else {
4677 pRoamProfile->AuthType.authType[0] =
4678 eCSR_AUTH_TYPE_UNKNOWN;
4679 }
4680 }
4681 break;
4682
4683 case eCSR_AUTH_TYPE_SHARED_KEY:
4684
4685 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4686 break;
4687 default:
4688
4689#ifdef FEATURE_WLAN_ESE
4690 hddLog(LOG1, FL("In default, unknown auth type."));
4691#endif /* FEATURE_WLAN_ESE */
4692 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4693 break;
4694 }
4695
4696 hddLog(LOG1, FL("Set roam Authtype to %d"),
4697 pWextState->roamProfile.AuthType.authType[0]);
4698
4699 EXIT();
4700 return 0;
4701}
4702
4703/**
4704 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4705 * to the CSR roam profile.
4706 *
4707 * @dev: Pointer to the net device.
4708 * @info: Pointer to the iw_request_info.
4709 * @wrqu: Pointer to the iwreq_data.
4710 * @extra: Pointer to the data.
4711 *
4712 * Return: 0 for success, error number on failure
4713 */
4714static int __iw_set_essid(struct net_device *dev,
4715 struct iw_request_info *info,
4716 union iwreq_data *wrqu, char *extra)
4717{
4718 unsigned long rc;
4719 uint32_t status = 0;
4720 hdd_wext_state_t *pWextState;
4721 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4722 hdd_context_t *hdd_ctx;
4723 uint32_t roamId;
4724 tCsrRoamProfile *pRoamProfile;
4725 eMib_dot11DesiredBssType connectedBssType;
4726 eCsrAuthType RSNAuthType;
4727 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4728 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4729 int ret;
4730
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004731 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004732
4733 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4734 ret = wlan_hdd_validate_context(hdd_ctx);
4735 if (0 != ret)
4736 return ret;
4737
4738 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION &&
4739 pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) {
4740 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4741 hdd_device_mode_to_string(pAdapter->device_mode),
4742 pAdapter->device_mode);
4743 return -EINVAL;
4744 }
4745
4746 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4747
4748 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4749 hddLog(LOG2, FL("Counter measure is in progress"));
4750 return -EBUSY;
4751 }
4752 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4753 return -EINVAL;
4754
4755 pRoamProfile = &pWextState->roamProfile;
4756 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4757 (eMib_dot11DesiredBssType_independent ==
4758 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304759 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004760
4761 /* Need to issue a disconnect to CSR. */
4762 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304763 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004764 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4765
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304766 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004767 rc = wait_for_completion_timeout(&pAdapter->
4768 disconnect_comp_var,
4769 msecs_to_jiffies
4770 (WLAN_WAIT_TIME_DISCONNECT));
4771 if (!rc)
4772 hddLog(LOGE, FL("Disconnect event timed out"));
4773 }
4774 }
4775
4776 /*
4777 * when cfg80211 defined, wpa_supplicant wext driver uses
4778 * zero-length, null-string ssid for force disconnection.
4779 * after disconnection (if previously connected) and cleaning ssid,
4780 * driver MUST return success.
4781 */
4782 if (0 == wrqu->essid.length)
4783 return 0;
4784
4785 status = hdd_wmm_get_uapsd_mask(pAdapter,
4786 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304787 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004788 pWextState->roamProfile.uapsd_mask = 0;
4789
4790 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4791
4792 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4793 wrqu->essid.length;
4794
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304795 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004796 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304797 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004798 ssId), extra, wrqu->essid.length);
4799 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4800 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4801
4802 /* set gen ie */
4803 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4804
4805 /* set auth */
4806 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4807 }
4808#ifdef FEATURE_WLAN_WAPI
4809 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4810 if (pAdapter->wapi_info.nWapiMode) {
4811 switch (pAdapter->wapi_info.wapiAuthMode) {
4812 case WAPI_AUTH_MODE_PSK:
4813 {
4814 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4815 pAdapter->wapi_info.wapiAuthMode);
4816 pRoamProfile->AuthType.numEntries = 1;
4817 pRoamProfile->AuthType.authType[0] =
4818 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4819 break;
4820 }
4821 case WAPI_AUTH_MODE_CERT:
4822 {
4823 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4824 pAdapter->wapi_info.wapiAuthMode);
4825 pRoamProfile->AuthType.numEntries = 1;
4826 pRoamProfile->AuthType.authType[0] =
4827 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4828 break;
4829 }
4830 } /* End of switch */
4831 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4832 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4833 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4834 pRoamProfile->EncryptionType.numEntries = 1;
4835 pRoamProfile->EncryptionType.encryptionType[0] =
4836 eCSR_ENCRYPT_TYPE_WPI;
4837 pRoamProfile->mcEncryptionType.numEntries = 1;
4838 pRoamProfile->mcEncryptionType.encryptionType[0] =
4839 eCSR_ENCRYPT_TYPE_WPI;
4840 }
4841 }
4842#endif /* FEATURE_WLAN_WAPI */
4843 /* if previous genIE is not NULL, update AssocIE */
4844 if (0 != pWextState->genIE.length) {
4845 memset(&pWextState->assocAddIE, 0,
4846 sizeof(pWextState->assocAddIE));
4847 memcpy(pWextState->assocAddIE.addIEdata,
4848 pWextState->genIE.addIEdata, pWextState->genIE.length);
4849 pWextState->assocAddIE.length = pWextState->genIE.length;
4850 pWextState->roamProfile.pAddIEAssoc =
4851 pWextState->assocAddIE.addIEdata;
4852 pWextState->roamProfile.nAddIEAssocLength =
4853 pWextState->assocAddIE.length;
4854
4855 /* clear previous genIE after use it */
4856 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4857 }
4858
4859 /*
4860 * Assumes it is not WPS Association by default, except when
4861 * pAddIEAssoc has WPS IE.
4862 */
4863 pWextState->roamProfile.bWPSAssociation = false;
4864
4865 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4866 pWextState->roamProfile.
4867 nAddIEAssocLength))
4868 pWextState->roamProfile.bWPSAssociation = true;
4869
4870 /* Disable auto BMPS entry by PMC until DHCP is done */
4871 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
4872 true);
4873
4874 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
4875
4876 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
4877 hdd_select_cbmode(pAdapter,
4878 (WLAN_HDD_GET_CTX(pAdapter))->config->
4879 AdHocChannel5G);
4880 }
4881 status = sme_roam_connect(hHal, pAdapter->sessionId,
4882 &(pWextState->roamProfile), &roamId);
4883 pRoamProfile->ChannelInfo.ChannelList = NULL;
4884 pRoamProfile->ChannelInfo.numOfChannels = 0;
4885
4886 EXIT();
4887 return status;
4888}
4889
4890/**
4891 * iw_set_essid() - set essid handler function
4892 * @dev: Pointer to the net device.
4893 * @info: Pointer to the iw_request_info.
4894 * @wrqu: Pointer to the iwreq_data.
4895 * @extra: Pointer to the data.
4896 *
4897 * Return: 0 for success, error number on failure
4898 */
4899int iw_set_essid(struct net_device *dev,
4900 struct iw_request_info *info,
4901 union iwreq_data *wrqu, char *extra)
4902{
4903 int ret;
4904
4905 cds_ssr_protect(__func__);
4906 ret = __iw_set_essid(dev, info, wrqu, extra);
4907 cds_ssr_unprotect(__func__);
4908
4909 return ret;
4910}
4911
4912/**
4913 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
4914 * @dev: pointer to the net device
4915 * @info: pointer to the iw request info
4916 * @dwrq: pointer to iw_point
4917 * @extra: pointer to the data
4918 *
4919 * Return: 0 on success, error number otherwise
4920 */
4921static int __iw_get_essid(struct net_device *dev,
4922 struct iw_request_info *info,
4923 struct iw_point *dwrq, char *extra)
4924{
4925 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4926 hdd_context_t *hdd_ctx;
4927 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4928 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4929 int ret;
4930
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004931 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004932
4933 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4934 ret = wlan_hdd_validate_context(hdd_ctx);
4935 if (0 != ret)
4936 return ret;
4937
4938 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
4939 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
4940 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
4941 || pHddStaCtx->conn_info.connState ==
4942 eConnectionState_IbssDisconnected)
4943 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
4944 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
4945 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
4946 dwrq->length);
4947 dwrq->flags = 1;
4948 } else {
4949 memset(extra, 0, dwrq->length);
4950 dwrq->length = 0;
4951 dwrq->flags = 0;
4952 }
4953 EXIT();
4954 return 0;
4955}
4956
4957/**
4958 * iw_get_essid() - get essid handler function
4959 * @dev: Pointer to the net device.
4960 * @info: Pointer to the iw_request_info.
4961 * @wrqu: Pointer to the iwreq_data.
4962 * @extra: Pointer to the data.
4963 *
4964 * Return: 0 for success, error number on failure
4965 */
4966int iw_get_essid(struct net_device *dev,
4967 struct iw_request_info *info,
4968 struct iw_point *wrqu, char *extra)
4969{
4970 int ret;
4971
4972 cds_ssr_protect(__func__);
4973 ret = __iw_get_essid(dev, info, wrqu, extra);
4974 cds_ssr_unprotect(__func__);
4975
4976 return ret;
4977}
4978
4979/**
4980 * __iw_set_auth() -
4981 * This function sets the auth type received from the wpa_supplicant
4982 * @dev: pointer to the net device
4983 * @info: pointer to the iw request info
4984 * @wrqu: pointer to iwreq_data
4985 * @extra: pointer to the data
4986 *
4987 * Return: 0 on success, error number otherwise
4988 */
4989static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
4990 union iwreq_data *wrqu, char *extra)
4991{
4992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4993 hdd_context_t *hdd_ctx;
4994 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4995 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4996 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4997 eCsrEncryptionType mcEncryptionType;
4998 eCsrEncryptionType ucEncryptionType;
4999 int ret;
5000
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005001 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005002
5003 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5004 ret = wlan_hdd_validate_context(hdd_ctx);
5005 if (0 != ret)
5006 return ret;
5007
5008 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5009 case IW_AUTH_WPA_VERSION:
5010 pWextState->wpaVersion = wrqu->param.value;
5011 break;
5012
5013 case IW_AUTH_CIPHER_PAIRWISE:
5014 {
5015 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5016 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5017 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5018 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5019 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5020 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5021 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5022 if ((IW_AUTH_KEY_MGMT_802_1X
5023 ==
5024 (pWextState->
5025 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5026 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5027 pHddStaCtx->conn_info.authType))
5028 /*Dynamic WEP key */
5029 ucEncryptionType =
5030 eCSR_ENCRYPT_TYPE_WEP40;
5031 else
5032 /*Static WEP key */
5033 ucEncryptionType =
5034 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5035 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5036 if ((IW_AUTH_KEY_MGMT_802_1X
5037 ==
5038 (pWextState->
5039 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5040 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5041 pHddStaCtx->conn_info.authType))
5042 /*Dynamic WEP key */
5043 ucEncryptionType =
5044 eCSR_ENCRYPT_TYPE_WEP104;
5045 else
5046 /*Static WEP key */
5047 ucEncryptionType =
5048 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5049 } else {
5050 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5051 wrqu->param.value);
5052 return -EINVAL;
5053 }
5054
5055 pRoamProfile->EncryptionType.numEntries = 1;
5056 pRoamProfile->EncryptionType.encryptionType[0] =
5057 ucEncryptionType;
5058 }
5059 break;
5060 case IW_AUTH_CIPHER_GROUP:
5061 {
5062 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5063 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5064 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5065 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5066 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5067 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5068 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5069 if ((IW_AUTH_KEY_MGMT_802_1X
5070 ==
5071 (pWextState->
5072 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5073 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5074 pHddStaCtx->conn_info.authType))
5075 mcEncryptionType =
5076 eCSR_ENCRYPT_TYPE_WEP40;
5077 else
5078 mcEncryptionType =
5079 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5080 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5081 /* Dynamic WEP keys won't work with shared keys */
5082 if ((IW_AUTH_KEY_MGMT_802_1X
5083 ==
5084 (pWextState->
5085 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5086 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5087 pHddStaCtx->conn_info.authType)) {
5088 mcEncryptionType =
5089 eCSR_ENCRYPT_TYPE_WEP104;
5090 } else {
5091 mcEncryptionType =
5092 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5093 }
5094 } else {
5095 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5096 wrqu->param.value);
5097 return -EINVAL;
5098 }
5099
5100 pRoamProfile->mcEncryptionType.numEntries = 1;
5101 pRoamProfile->mcEncryptionType.encryptionType[0] =
5102 mcEncryptionType;
5103 }
5104 break;
5105
5106 case IW_AUTH_80211_AUTH_ALG:
5107 {
5108 /* Save the auth algo here and set auth type to SME Roam profile
5109 in the iw_set_ap_address */
5110 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5111 pHddStaCtx->conn_info.authType =
5112 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5113
5114 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5115 pHddStaCtx->conn_info.authType =
5116 eCSR_AUTH_TYPE_SHARED_KEY;
5117
5118 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5119 /*Not supported */
5120 pHddStaCtx->conn_info.authType =
5121 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5122 pWextState->roamProfile.AuthType.authType[0] =
5123 pHddStaCtx->conn_info.authType;
5124 }
5125 break;
5126
5127 case IW_AUTH_KEY_MGMT:
5128 {
5129#ifdef FEATURE_WLAN_ESE
5130#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5131 /*Check for CCKM AKM type */
5132 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5133 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5134 /* Set the CCKM bit in authKeyMgmt */
5135 /*
5136 * Right now, this breaks all ref to authKeyMgmt because
5137 * our code doesn't realize it is a "bitfield"
5138 */
5139 pWextState->authKeyMgmt |=
5140 IW_AUTH_KEY_MGMT_CCKM;
5141 /* Set the key management to 802.1X */
5142 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5143 pWextState->isESEConnection = true;
5144 /*
5145 * This is test code. I need to actually KNOW whether
5146 * this is an RSN Assoc or WPA.
5147 */
5148 pWextState->collectedAuthType =
5149 eCSR_AUTH_TYPE_CCKM_RSN;
5150 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5151 /* Save the key management */
5152 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5153 pWextState->collectedAuthType =
5154 eCSR_AUTH_TYPE_RSN;
5155 } else
5156 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5157 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5158 /* Save the key management anyway */
5159 pWextState->authKeyMgmt = wrqu->param.value;
5160 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5161 /* Save the key management */
5162 pWextState->authKeyMgmt |=
5163 IW_AUTH_KEY_MGMT_802_1X;
5164 pWextState->collectedAuthType =
5165 eCSR_AUTH_TYPE_RSN;
5166 }
5167#else
5168 /* Save the key management */
5169 pWextState->authKeyMgmt = wrqu->param.value;
5170#endif /* FEATURE_WLAN_ESE */
5171 }
5172 break;
5173
5174 case IW_AUTH_TKIP_COUNTERMEASURES:
5175 {
5176 if (wrqu->param.value) {
5177 hddLog(LOG2,
5178 "Counter Measure started %d",
5179 wrqu->param.value);
5180 pWextState->mTKIPCounterMeasures =
5181 TKIP_COUNTER_MEASURE_STARTED;
5182 } else {
5183 hddLog(LOG2,
5184 "Counter Measure stopped=%d",
5185 wrqu->param.value);
5186 pWextState->mTKIPCounterMeasures =
5187 TKIP_COUNTER_MEASURE_STOPED;
5188 }
5189 }
5190 break;
5191 case IW_AUTH_DROP_UNENCRYPTED:
5192 case IW_AUTH_WPA_ENABLED:
5193 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5194 case IW_AUTH_ROAMING_CONTROL:
5195 case IW_AUTH_PRIVACY_INVOKED:
5196
5197 default:
5198
5199 hddLog(LOGW, FL("called with unsupported auth type %d"),
5200 wrqu->param.flags & IW_AUTH_INDEX);
5201 break;
5202 }
5203
5204 EXIT();
5205 return 0;
5206}
5207
5208/**
5209 * iw_set_auth() - set auth callback function
5210 * @dev: Pointer to the net device.
5211 * @info: Pointer to the iw_request_info.
5212 * @wrqu: Pointer to the iwreq_data.
5213 * @extra: Pointer to the data.
5214 *
5215 * Return: 0 for success, error number on failure.
5216 */
5217int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5218 union iwreq_data *wrqu, char *extra)
5219{
5220 int ret;
5221
5222 cds_ssr_protect(__func__);
5223 ret = __iw_set_auth(dev, info, wrqu, extra);
5224 cds_ssr_unprotect(__func__);
5225
5226 return ret;
5227}
5228
5229/**
5230 * __iw_get_auth() -
5231 * This function returns the auth type to the wpa_supplicant
5232 * @dev: pointer to the net device
5233 * @info: pointer to the iw request info
5234 * @wrqu: pointer to iwreq_data
5235 * @extra: pointer to the data
5236 *
5237 * Return: 0 on success, error number otherwise
5238 */
5239static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5240 union iwreq_data *wrqu, char *extra)
5241{
5242 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5243 hdd_context_t *hdd_ctx;
5244 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5245 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5246 int ret;
5247
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005248 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005249
5250 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5251 ret = wlan_hdd_validate_context(hdd_ctx);
5252 if (0 != ret)
5253 return ret;
5254
5255 switch (pRoamProfile->negotiatedAuthType) {
5256 case eCSR_AUTH_TYPE_WPA_NONE:
5257 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5258 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5259 break;
5260 case eCSR_AUTH_TYPE_WPA:
5261 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5262 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5263 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005264
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005265 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005266 case eCSR_AUTH_TYPE_RSN:
5267 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5268 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5269 break;
5270 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5271 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5272 break;
5273 case eCSR_AUTH_TYPE_SHARED_KEY:
5274 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5275 break;
5276 case eCSR_AUTH_TYPE_UNKNOWN:
5277 hddLog(LOG1, FL("called with unknown auth type"));
5278 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5279 break;
5280 case eCSR_AUTH_TYPE_AUTOSWITCH:
5281 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5282 break;
5283 case eCSR_AUTH_TYPE_WPA_PSK:
5284 hddLog(LOG1, FL("called with WPA PSK auth type"));
5285 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5286 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005287
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005288 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005289 case eCSR_AUTH_TYPE_RSN_PSK:
5290#ifdef WLAN_FEATURE_11W
5291 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5292 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5293#endif
5294 hddLog(LOG1, FL("called with RSN PSK auth type"));
5295 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5296 return -EIO;
5297 default:
5298 hddLog(LOGE, FL("called with unknown auth type"));
5299 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5300 return -EIO;
5301 }
5302 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5303 switch (pRoamProfile->negotiatedUCEncryptionType) {
5304 case eCSR_ENCRYPT_TYPE_NONE:
5305 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5306 break;
5307 case eCSR_ENCRYPT_TYPE_WEP40:
5308 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5309 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5310 break;
5311 case eCSR_ENCRYPT_TYPE_TKIP:
5312 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5313 break;
5314 case eCSR_ENCRYPT_TYPE_WEP104:
5315 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5316 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5317 break;
5318 case eCSR_ENCRYPT_TYPE_AES:
5319 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5320 break;
5321 default:
5322 hddLog(LOG1, FL("called with unknown auth type %d"),
5323 pRoamProfile->negotiatedUCEncryptionType);
5324 return -EIO;
5325 }
5326 }
5327
5328 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5329 switch (pRoamProfile->negotiatedMCEncryptionType) {
5330 case eCSR_ENCRYPT_TYPE_NONE:
5331 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5332 break;
5333 case eCSR_ENCRYPT_TYPE_WEP40:
5334 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5335 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5336 break;
5337 case eCSR_ENCRYPT_TYPE_TKIP:
5338 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5339 break;
5340 case eCSR_ENCRYPT_TYPE_WEP104:
5341 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5342 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5343 break;
5344 case eCSR_ENCRYPT_TYPE_AES:
5345 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5346 break;
5347 default:
5348 hddLog(LOG1, FL("called with unknown auth type %d"),
5349 pRoamProfile->negotiatedMCEncryptionType);
5350 return -EIO;
5351 }
5352 }
5353
5354 hddLog(LOG1, FL("called with auth type %d"),
5355 pRoamProfile->AuthType.authType[0]);
5356 EXIT();
5357 return 0;
5358}
5359
5360/**
5361 * iw_get_auth() - get auth callback function
5362 * @dev: Pointer to the net device.
5363 * @info: Pointer to the iw_request_info.
5364 * @wrqu: Pointer to the iwreq_data.
5365 * @extra: Pointer to the data.
5366 *
5367 * Return: 0 for success, error number on failure.
5368 */
5369int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5370 union iwreq_data *wrqu, char *extra)
5371{
5372 int ret;
5373
5374 cds_ssr_protect(__func__);
5375 ret = __iw_get_auth(dev, info, wrqu, extra);
5376 cds_ssr_unprotect(__func__);
5377
5378 return ret;
5379}
5380
5381/**
5382 * __iw_set_ap_address() - set ap address
5383 * @dev: pointer to the net device
5384 * @info: pointer to the iw request info
5385 * @wrqu: pointer to iwreq_data
5386 * @extra: pointer to the data
5387 *
5388 * This function updates the HDD global station context connection info
5389 * BSSID with the MAC address received from the wpa_supplicant.
5390 *
5391 * Return: 0 on success, error number otherwise
5392 */
5393static int __iw_set_ap_address(struct net_device *dev,
5394 struct iw_request_info *info,
5395 union iwreq_data *wrqu, char *extra)
5396{
5397
5398 hdd_adapter_t *adapter;
5399 hdd_context_t *hdd_ctx;
5400 hdd_station_ctx_t *pHddStaCtx =
5401 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5402 uint8_t *pMacAddress = NULL;
5403 int ret;
5404
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005405 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005406
5407 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5408
5409 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5410 ret = wlan_hdd_validate_context(hdd_ctx);
5411 if (0 != ret)
5412 return ret;
5413
5414 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5415 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305416 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305417 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005418 EXIT();
5419
5420 return 0;
5421}
5422
5423/**
5424 * iw_set_ap_address() - set ap addresses callback function
5425 * @dev: Pointer to the net device.
5426 * @info: Pointer to the iw_request_info.
5427 * @wrqu: Pointer to the iwreq_data.
5428 * @extra: Pointer to the data.
5429 *
5430 * Return: 0 for success, error number on failure.
5431 */
5432int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5433 union iwreq_data *wrqu, char *extra)
5434{
5435 int ret;
5436
5437 cds_ssr_protect(__func__);
5438 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5439 cds_ssr_unprotect(__func__);
5440
5441 return ret;
5442}
5443
5444/**
5445 * __iw_get_ap_address() - get ap address
5446 * @dev: pointer to the net device
5447 * @info: pointer to the iw request info
5448 * @wrqu: pointer to iwreq_data
5449 * @extra: pointer to the data
5450 *
5451 * This function returns currently associated BSSID.
5452 *
5453 * Return: 0 on success, error number otherwise
5454 */
5455static int __iw_get_ap_address(struct net_device *dev,
5456 struct iw_request_info *info,
5457 union iwreq_data *wrqu, char *extra)
5458{
5459 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5460 hdd_context_t *hdd_ctx;
5461 hdd_station_ctx_t *pHddStaCtx =
5462 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5463 int ret;
5464
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005465 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005466
5467 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5468 ret = wlan_hdd_validate_context(hdd_ctx);
5469 if (0 != ret)
5470 return ret;
5471
5472 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5473 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305474 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005475 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305476 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005477 } else {
5478 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5479 }
5480 EXIT();
5481 return 0;
5482}
5483
5484/**
5485 * iw_get_ap_address() - get ap addresses callback function
5486 * @dev: Pointer to the net device.
5487 * @info: Pointer to the iw_request_info.
5488 * @wrqu: Pointer to the iwreq_data.
5489 * @extra: Pointer to the data.
5490 *
5491 * Return: 0 for success, error number on failure.
5492 */
5493int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5494 union iwreq_data *wrqu, char *extra)
5495{
5496 int ret;
5497
5498 cds_ssr_protect(__func__);
5499 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5500 cds_ssr_unprotect(__func__);
5501
5502 return ret;
5503}