blob: 85debbd99df03fe1989b8f94b9462a57ffa60937 [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"
Himanshu Agarwal11c874a2016-05-06 18:35:29 +053059#include "ol_rx_fwd.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080060#include "cdp_txrx_flow_ctrl_legacy.h"
61#include "cdp_txrx_peer_ops.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062
63/* These are needed to recognize WPA and RSN suite types */
64#define HDD_WPA_OUI_SIZE 4
65#define HDD_RSN_OUI_SIZE 4
66uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
67uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
68uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
69uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
70uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
71uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
72
73#ifdef FEATURE_WLAN_ESE
74/* CCKM */
75uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
76/* CCKM */
77uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
78#endif /* FEATURE_WLAN_ESE */
79
80/* group cipher */
81uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
82
83/* WEP-40 or RSN */
84uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
85
86/* TKIP or RSN-PSK */
87uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
88
89/* Reserved */
90uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
91
92/* AES-CCMP */
93uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
94
95/* WEP-104 */
96uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
97
98#ifdef WLAN_FEATURE_11W
99/* RSN-PSK-SHA256 */
100uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
101
102/* RSN-8021X-SHA256 */
103uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
104#endif
105
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800106/* Offset where the EID-Len-IE, start. */
107#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
108#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800109
110#define BEACON_FRAME_IES_OFFSET 12
111#define HDD_PEER_AUTHORIZE_WAIT 10
112
113/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700114 * beacon_filter_table - table of IEs used for beacon filtering
115 */
116static const int beacon_filter_table[] = {
117 SIR_MAC_DS_PARAM_SET_EID,
118 SIR_MAC_ERP_INFO_EID,
119 SIR_MAC_EDCA_PARAM_SET_EID,
120 SIR_MAC_QOS_CAPABILITY_EID,
121 SIR_MAC_HT_INFO_EID,
122 SIR_MAC_VHT_OPMODE_EID,
123 SIR_MAC_VHT_OPERATION_EID,
124};
125
126/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800127 * hdd_conn_set_authenticated() - set authentication state
128 * @pAdapter: pointer to the adapter
129 * @authState: authentication state
130 *
131 * This function updates the global HDD station context
132 * authentication state.
133 *
134 * Return: none
135 */
136static void
137hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
138{
139 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
140 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
141
142 /* save the new connection state */
143 hddLog(LOG1,
144 FL("Authenticated state Changed from oldState:%d to State:%d"),
145 pHddStaCtx->conn_info.uIsAuthenticated, authState);
146 pHddStaCtx->conn_info.uIsAuthenticated = authState;
147
148 /* Check is pending ROC request or not when auth state changed */
149 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
150}
151
152/**
153 * hdd_conn_set_connection_state() - set connection state
154 * @pAdapter: pointer to the adapter
155 * @connState: connection state
156 *
157 * This function updates the global HDD station context connection state.
158 *
159 * Return: none
160 */
161void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
162 eConnectionState connState)
163{
164 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
165 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
166
167 /* save the new connection state */
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530168 hdd_info("%pS Changed connectionState Changed from oldState:%d to State:%d",
169 (void *)_RET_IP_, pHddStaCtx->conn_info.connState,
170 connState);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800171 pHddStaCtx->conn_info.connState = connState;
172
173 /* Check is pending ROC request or not when connection state changed */
174 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
175}
176
177/**
178 * hdd_conn_get_connection_state() - get connection state
179 * @pAdapter: pointer to the adapter
180 * @pConnState: pointer to connection state
181 *
182 * This function updates the global HDD station context connection state.
183 *
184 * Return: true if (Infra Associated or IBSS Connected)
185 * and sets output parameter pConnState;
186 * false otherwise
187 */
188static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
189 eConnectionState *pConnState)
190{
191 bool fConnected = false;
192 eConnectionState connState;
193
194 /* get the connection state. */
195 connState = pHddStaCtx->conn_info.connState;
196
197 if (eConnectionState_Associated == connState ||
198 eConnectionState_IbssConnected == connState ||
199 eConnectionState_IbssDisconnected == connState) {
200 fConnected = true;
201 }
202
203 if (pConnState)
204 *pConnState = connState;
205
206 return fConnected;
207}
208
209/**
210 * hdd_is_connecting() - Function to check connection progress
211 * @hdd_sta_ctx: pointer to global HDD Station context
212 *
213 * Return: true if connecting, false otherwise
214 */
215bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
216{
217 return hdd_sta_ctx->conn_info.connState ==
218 eConnectionState_Connecting;
219}
220
221/**
222 * hdd_conn_is_connected() - Function to check connection status
223 * @pHddStaCtx: pointer to global HDD Station context
224 *
225 * Return: false if any errors encountered, true otherwise
226 */
227bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
228{
229 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
230}
231
232/**
233 * hdd_conn_get_connected_band() - get current connection radio band
234 * @pHddStaCtx: pointer to global HDD Station context
235 *
236 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
237 * eCSR_BAND_ALL if not connected
238 */
239eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
240{
241 uint8_t staChannel = 0;
242
243 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
244 staChannel = pHddStaCtx->conn_info.operationChannel;
245
246 if (staChannel > 0 && staChannel < 14)
247 return eCSR_BAND_24;
248 else if (staChannel >= 36 && staChannel <= 184)
249 return eCSR_BAND_5G;
250 else /* If station is not connected return as eCSR_BAND_ALL */
251 return eCSR_BAND_ALL;
252}
253
254/**
255 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
256 * @pHddStaCtx: pointer to global HDD Station context
257 * @pConnectedCipherAlgo: pointer to connected cipher algo
258 *
259 * Return: false if any errors encountered, true otherwise
260 */
261static inline bool
262hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
263 eCsrEncryptionType *pConnectedCipherAlgo)
264{
265 bool fConnected = false;
266
267 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
268
269 if (pConnectedCipherAlgo)
270 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
271
272 return fConnected;
273}
274
275/**
276 * hdd_conn_get_connected_bss_type() - get current bss type
277 * @pHddStaCtx: pointer to global HDD Station context
278 * @pConnectedBssType: pointer to connected bss type
279 *
280 * Return: false if any errors encountered, true otherwise
281 */
282inline bool
283hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
284 eMib_dot11DesiredBssType *pConnectedBssType)
285{
286 bool fConnected = false;
287
288 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
289
290 if (pConnectedBssType) {
291 *pConnectedBssType =
292 pHddStaCtx->conn_info.connDot11DesiredBssType;
293 }
294
295 return fConnected;
296}
297
298/**
299 * hdd_conn_save_connected_bss_type() - set connected bss type
300 * @pHddStaCtx: pointer to global HDD Station context
301 * @csr_roamBssType: bss type
302 *
303 * Return: none
304 */
305static inline void
306hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
307 eCsrRoamBssType csr_roamBssType)
308{
309 switch (csr_roamBssType) {
310 case eCSR_BSS_TYPE_INFRASTRUCTURE:
311 pHddStaCtx->conn_info.connDot11DesiredBssType =
312 eMib_dot11DesiredBssType_infrastructure;
313 break;
314
315 case eCSR_BSS_TYPE_IBSS:
316 case eCSR_BSS_TYPE_START_IBSS:
317 pHddStaCtx->conn_info.connDot11DesiredBssType =
318 eMib_dot11DesiredBssType_independent;
319 break;
320
321 /** We will never set the BssType to 'any' when attempting a connection
322 so CSR should never send this back to us.*/
323 case eCSR_BSS_TYPE_ANY:
324 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530325 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800326 break;
327 }
328}
329
330/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700331 * hdd_remove_beacon_filter() - remove beacon filter
332 * @adapter: Pointer to the hdd adapter
333 *
334 * Return: 0 on success and errno on failure
335 */
336static int hdd_remove_beacon_filter(hdd_adapter_t *adapter)
337{
338 QDF_STATUS status;
339 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
340
341 status = sme_remove_beacon_filter(hdd_ctx->hHal,
342 adapter->sessionId);
343 if (!QDF_IS_STATUS_SUCCESS(status)) {
344 hdd_err("sme_remove_beacon_filter() failed");
345 return -EFAULT;
346 }
347
348 return 0;
349}
350
351/**
352 * hdd_add_beacon_filter() - add beacon filter
353 * @adapter: Pointer to the hdd adapter
354 *
355 * Return: 0 on success and errno on failure
356 */
357static int hdd_add_beacon_filter(hdd_adapter_t *adapter)
358{
359 int i;
360 uint32_t ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST] = {0};
361 QDF_STATUS status;
362 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
363
364 for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++)
365 qdf_set_bit((beacon_filter_table[i] - 1),
366 (unsigned long int *)ie_map);
367
368 status = sme_add_beacon_filter(hdd_ctx->hHal,
369 adapter->sessionId, ie_map);
370 if (!QDF_IS_STATUS_SUCCESS(status)) {
371 hdd_err("sme_add_beacon_filter() failed");
372 return -EFAULT;
373 }
374 return 0;
375}
376
377/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800378 * hdd_conn_save_connect_info() - save current connection information
379 * @pAdapter: pointer to adapter
380 * @pRoamInfo: pointer to roam info
381 * @eBssType: bss type
382 *
383 * Return: none
384 */
385static void
386hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
387 eCsrRoamBssType eBssType)
388{
389 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
390 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
391
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530392 QDF_ASSERT(pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800393
394 if (pRoamInfo) {
395 /* Save the BSSID for the connection */
396 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530397 QDF_ASSERT(pRoamInfo->pBssDesc);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530398 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399 &pRoamInfo->bssid);
400
401 /*
402 * Save the Station ID for this station from
403 * the 'Roam Info'. For IBSS mode, staId is
404 * assigned in NEW_PEER_IND. For reassoc,
405 * the staID doesn't change and it may be invalid
406 * in this structure so no change here.
407 */
408 if (!pRoamInfo->fReassocReq) {
409 pHddStaCtx->conn_info.staId[0] =
410 pRoamInfo->staId;
411 }
412 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530413 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 &pRoamInfo->bssid);
415 } else {
416 /*
417 * can't happen. We need a valid IBSS or Infra setting
418 * in the BSSDescription or we can't function.
419 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530420 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800421 }
422
423 /* notify WMM */
424 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
425
426 if (!pRoamInfo->u.pConnectedProfile) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530427 QDF_ASSERT(pRoamInfo->u.pConnectedProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 } else {
429 /* Get Multicast Encryption Type */
430 encryptType =
431 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
432 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
433 /* Get Unicast Encryption Type */
434 encryptType =
435 pRoamInfo->u.pConnectedProfile->EncryptionType;
436 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
437
438 pHddStaCtx->conn_info.authType =
439 pRoamInfo->u.pConnectedProfile->AuthType;
440
441 pHddStaCtx->conn_info.operationChannel =
442 pRoamInfo->u.pConnectedProfile->operationChannel;
443
444 /* Save the ssid for the connection */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530445 qdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800446 &pRoamInfo->u.pConnectedProfile->SSID,
447 sizeof(tSirMacSSid));
448
449 /* Save dot11mode in which STA associated to AP */
450 pHddStaCtx->conn_info.dot11Mode =
451 pRoamInfo->u.pConnectedProfile->dot11Mode;
452
453 pHddStaCtx->conn_info.proxyARPService =
454 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530455
456 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
457
458 pHddStaCtx->conn_info.rate_flags =
459 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 }
461 }
462 /* save the connected BssType */
463 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
464}
465
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466/**
467 * hdd_send_ft_assoc_response() - send fast transition assoc response
468 * @dev: pointer to net device
469 * @pAdapter: pointer to adapter
470 * @pCsrRoamInfo: pointer to roam info
471 *
472 * Send the 11R key information to the supplicant. Only then can the supplicant
473 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
474 * for the same purpose.)
475 *
476 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
477 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
478 * This is the Assoc Response.
479 *
480 * Return: none
481 */
482static void
483hdd_send_ft_assoc_response(struct net_device *dev,
484 hdd_adapter_t *pAdapter,
485 tCsrRoamInfo *pCsrRoamInfo)
486{
487 union iwreq_data wrqu;
488 char *buff;
489 unsigned int len = 0;
490 u8 *pFTAssocRsp = NULL;
491
492 if (pCsrRoamInfo->nAssocRspLength == 0) {
493 hddLog(LOGE,
494 FL("pCsrRoamInfo->nAssocRspLength=%d"),
495 (int)pCsrRoamInfo->nAssocRspLength);
496 return;
497 }
498
499 pFTAssocRsp =
500 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
501 pCsrRoamInfo->nAssocReqLength);
502 if (pFTAssocRsp == NULL) {
503 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
504 return;
505 }
506 /* pFTAssocRsp needs to point to the IEs */
507 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
508 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
509 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
510
511 /* We need to send the IEs to the supplicant. */
512 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
513 if (buff == NULL) {
514 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
515 return;
516 }
517 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
518 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
519 wrqu.data.length = len;
520 memset(buff, 0, IW_GENERIC_IE_MAX);
521 memcpy(buff, pFTAssocRsp, len);
522 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
523
524 kfree(buff);
525}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527/**
528 * hdd_send_ft_event() - send fast transition event
529 * @pAdapter: pointer to adapter
530 *
531 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
532 * FT events to the supplicant. At the reception of Auth2 we send the RIC
533 * followed by the auth response IEs to the supplicant.
534 * Once both are received in the supplicant, an FT event is generated
535 * to the supplicant.
536 *
537 * Return: none
538 */
539static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
540{
541 uint16_t auth_resp_len = 0;
542 uint32_t ric_ies_length = 0;
543 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
544
545#if defined(KERNEL_SUPPORT_11R_CFG80211)
546 struct cfg80211_ft_event_params ftEvent;
547 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
548 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
549 struct net_device *dev = pAdapter->dev;
550#else
551 char *buff;
552 union iwreq_data wrqu;
553 uint16_t str_len;
554#endif
555
556#if defined(KERNEL_SUPPORT_11R_CFG80211)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530557 qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
558 qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559
560 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
561 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
562 if (ric_ies_length == 0) {
563 hddLog(LOGW,
564 FL("RIC IEs is of length 0 not sending RIC Information for now"));
565 }
566
567 ftEvent.ric_ies = ricIe;
568 ftEvent.ric_ies_len = ric_ies_length;
569 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
570
571 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
572 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
573 &auth_resp_len);
574
575 if (auth_resp_len == 0) {
576 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
577 return;
578 }
579
580 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
581
582 ftEvent.target_ap = ftIe;
583
Anurag Chouhan6d760662016-02-20 16:05:43 +0530584 ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
585 ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586
587 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
588 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
589 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
590 ftEvent.target_ap[0], ftEvent.target_ap[1],
591 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
592 ftEvent.target_ap[5]);
593
594 (void)cfg80211_ft_event(dev, &ftEvent);
595
596#else
597 /* We need to send the IEs to the supplicant */
598 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
599 if (buff == NULL) {
600 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
601 return;
602 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530603 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604
605 /* Sme needs to send the RIC IEs first */
606 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
607 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
608 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
609 &ric_ies_length);
610 if (ric_ies_length == 0) {
611 hddLog(LOGW,
612 FL("RIC IEs is of length 0 not sending RIC Information for now"));
613 } else {
614 wrqu.data.length = str_len + ric_ies_length;
615 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
616 }
617
618 /* Sme needs to provide the Auth Resp */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530619 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800620 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
621 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
622 (u8 *) &buff[str_len],
623 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
624
625 if (auth_resp_len == 0) {
626 kfree(buff);
627 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
628 return;
629 }
630
631 wrqu.data.length = str_len + auth_resp_len;
632 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
633
634 kfree(buff);
635#endif
636}
637
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638#ifdef FEATURE_WLAN_ESE
639/**
640 * hdd_send_new_ap_channel_info() - send new ap channel info
641 * @dev: pointer to net device
642 * @pAdapter: pointer to adapter
643 * @pCsrRoamInfo: pointer to roam info
644 *
645 * Send the ESE required "new AP Channel info" to the supplicant.
646 * (This keeps the supplicant "up to date" on the current channel.)
647 *
648 * The current (new AP) channel information is passed in.
649 *
650 * Return: none
651 */
652static void
653hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
654 tCsrRoamInfo *pCsrRoamInfo)
655{
656 union iwreq_data wrqu;
657 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
658
659 if (descriptor == NULL) {
660 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
661 return;
662 }
663 /*
664 * Send the Channel event, the supplicant needs this to generate
665 * the Adjacent AP report.
666 */
667 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
668 descriptor->channelId);
669 memset(&wrqu, '\0', sizeof(wrqu));
670 wrqu.freq.m = descriptor->channelId;
671 wrqu.freq.e = 0;
672 wrqu.freq.i = 0;
673 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
674}
675
676#endif /* FEATURE_WLAN_ESE */
677
678/**
679 * hdd_send_update_beacon_ies_event() - send update beacons ie event
680 * @pAdapter: pointer to adapter
681 * @pCsrRoamInfo: pointer to roam info
682 *
683 * Return: none
684 */
685static void
686hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
687 tCsrRoamInfo *pCsrRoamInfo)
688{
689 union iwreq_data wrqu;
690 u8 *pBeaconIes;
691 u8 currentLen = 0;
692 char *buff;
693 int totalIeLen = 0, currentOffset = 0, strLen;
694
695 memset(&wrqu, '\0', sizeof(wrqu));
696
697 if (0 == pCsrRoamInfo->nBeaconLength) {
698 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
699 return;
700 }
701 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
702 if (pBeaconIes == NULL) {
703 hddLog(LOGW, FL("Beacon IEs is NULL"));
704 return;
705 }
706 /* pBeaconIes needs to point to the IEs */
707 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
708 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
709 hddLog(LOG1, FL("Beacon IEs length = %d"),
710 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
711
712 /* We need to send the IEs to the supplicant. */
713 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
714 if (buff == NULL) {
715 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
716 return;
717 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530718 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719
720 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
721 currentLen = strLen + 1;
722
723 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
724 do {
725 /*
726 * If the beacon size exceeds max CUSTOM event size, break it
727 * into chunks of CUSTOM event max size and send it to
728 * supplicant. Changes are done in supplicant to handle this.
729 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530730 qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 currentLen =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530732 QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530733 qdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800734 currentLen);
735 currentOffset += currentLen;
736 totalIeLen -= currentLen;
737 wrqu.data.length = strLen + 1 + currentLen;
738 if (totalIeLen)
739 buff[strLen] = 1; /* more chunks pending */
740 else
741 buff[strLen] = 0; /* last chunk */
742
743 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
744 currentLen);
745 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
746 } while (totalIeLen > 0);
747
748 kfree(buff);
749}
750
751/**
752 * hdd_send_association_event() - send association event
753 * @dev: pointer to net device
754 * @pCsrRoamInfo: pointer to roam info
755 *
756 * Return: none
757 */
758static void hdd_send_association_event(struct net_device *dev,
759 tCsrRoamInfo *pCsrRoamInfo)
760{
761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
762 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
763 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
764 union iwreq_data wrqu;
765 int we_event;
766 char *msg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530767 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800768
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 /* Added to find the auth type on the fly at run time */
770 /* rather than with cfg to see if FT is enabled */
771 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
772 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773
774 memset(&wrqu, '\0', sizeof(wrqu));
775 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
776 we_event = SIOCGIWAP;
777#ifdef WLAN_FEATURE_ROAM_OFFLOAD
778 if (NULL != pCsrRoamInfo)
779 if (pCsrRoamInfo->roamSynchInProgress)
780 /* change logging before release */
781 hddLog(LOG4, "LFR3:hdd_send_association_event");
782#endif
783 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
Abhishek Singh1c676222016-05-09 14:20:28 +0530784 tSirSmeChanInfo chan_info;
785
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786 if (!pCsrRoamInfo) {
787 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
788 return;
789 }
790
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800791 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
792 cds_incr_active_session(pAdapter->device_mode,
793 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800794 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
795 sizeof(pCsrRoamInfo->pBssDesc->bssId));
796
797#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -0800798 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799 if (global_p2p_connection_status ==
800 P2P_CLIENT_CONNECTING_STATE_1) {
801 global_p2p_connection_status =
802 P2P_CLIENT_CONNECTED_STATE_1;
803 hddLog(LOGE,
804 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
805 } else if (global_p2p_connection_status ==
806 P2P_CLIENT_CONNECTING_STATE_2) {
807 global_p2p_connection_status =
808 P2P_CLIENT_COMPLETED_STATE;
809 hddLog(LOGE,
810 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
811 }
812 }
813#endif
814 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
815 MAC_ADDRESS_STR "\n",
816 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
817 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
818 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
819
820 /*
821 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
822 * is Enabled Or Send IWEVASSOCRESPIE Event if
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -0800823 * fFTEnable is true.
824 * Send FT Keys to the supplicant when FT is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800825 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 if ((pRoamProfile->AuthType.authType[0] ==
827 eCSR_AUTH_TYPE_FT_RSN_PSK)
828 || (pRoamProfile->AuthType.authType[0] ==
829 eCSR_AUTH_TYPE_FT_RSN)
830#ifdef FEATURE_WLAN_ESE
831 || (pRoamProfile->AuthType.authType[0] ==
832 eCSR_AUTH_TYPE_CCKM_RSN)
833 || (pRoamProfile->AuthType.authType[0] ==
834 eCSR_AUTH_TYPE_CCKM_WPA)
835#endif
836 ) {
837 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
838 }
Abhishek Singh1c676222016-05-09 14:20:28 +0530839 qdf_copy_macaddr(&peerMacAddr,
840 &pHddStaCtx->conn_info.bssId);
841 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
842 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
843 chan_info.info = pCsrRoamInfo->chan_info.info;
844 chan_info.band_center_freq1 =
845 pCsrRoamInfo->chan_info.band_center_freq1;
846 chan_info.band_center_freq2 =
847 pCsrRoamInfo->chan_info.band_center_freq2;
848 chan_info.reg_info_1 =
849 pCsrRoamInfo->chan_info.reg_info_1;
850 chan_info.reg_info_2 =
851 pCsrRoamInfo->chan_info.reg_info_2;
852 /* send peer status indication to oem app */
853 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
854 ePeerConnected,
855 pCsrRoamInfo->
856 timingMeasCap,
857 pAdapter->sessionId,
858 &chan_info,
859 pAdapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800860
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861#ifdef MSM_PLATFORM
862#ifdef CONFIG_CNSS
863 /* start timer in sta/p2p_cli */
864 spin_lock_bh(&pHddCtx->bus_bw_lock);
865 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
866 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +0530867 ol_get_intra_bss_fwd_pkts_count(pAdapter->sessionId,
868 &pAdapter->prev_fwd_tx_packets,
869 &pAdapter->prev_fwd_rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800870 spin_unlock_bh(&pHddCtx->bus_bw_lock);
871 hdd_start_bus_bw_compute_timer(pAdapter);
872#endif
873#endif
874 } else if (eConnectionState_IbssConnected == /* IBss Associated */
875 pHddStaCtx->conn_info.connState) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800876 cds_update_connection_info(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
878 ETH_ALEN);
879 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
880 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
881 } else { /* Not Associated */
882
883 pr_info("wlan: disconnected\n");
884 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +0530885 cds_decr_session_set_pcl(pAdapter->device_mode,
886 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888
889#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
890 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
891#endif
892
Abhishek Singh1c676222016-05-09 14:20:28 +0530893 if ((pAdapter->device_mode == QDF_STA_MODE) ||
894 (pAdapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530895 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896 &pHddStaCtx->conn_info.bssId);
897
898 /* send peer status indication to oem app */
899 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
Abhishek Singh1c676222016-05-09 14:20:28 +0530900 ePeerDisconnected, 0,
901 pAdapter->sessionId,
902 NULL,
903 pAdapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800904 }
905#ifdef WLAN_FEATURE_LPSS
906 pAdapter->rssi_send = false;
907 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
908#endif
909#ifdef FEATURE_WLAN_TDLS
Krunal Sonibe766b02016-03-10 13:00:44 -0800910 if ((pAdapter->device_mode == QDF_STA_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800911 (pCsrRoamInfo)) {
912 hddLog(LOG4,
913 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
914 pCsrRoamInfo->tdls_prohibited,
915 pCsrRoamInfo->tdls_chan_swit_prohibited);
916
917 wlan_hdd_update_tdls_info(pAdapter,
918 pCsrRoamInfo->tdls_prohibited,
919 pCsrRoamInfo->tdls_chan_swit_prohibited);
920 }
921#endif
922#ifdef MSM_PLATFORM
923 /* stop timer in sta/p2p_cli */
924 spin_lock_bh(&pHddCtx->bus_bw_lock);
925 pAdapter->prev_tx_packets = 0;
926 pAdapter->prev_rx_packets = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +0530927 pAdapter->prev_fwd_tx_packets = 0;
928 pAdapter->prev_fwd_rx_packets = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800929 spin_unlock_bh(&pHddCtx->bus_bw_lock);
930 hdd_stop_bus_bw_compute_timer(pAdapter);
931#endif
932 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800933 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800934 /* Send SCC/MCC Switching event to IPA */
935 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
936
937 msg = NULL;
938 /*During the WLAN uninitialization,supplicant is stopped before the
939 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800940 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800941 wireless_send_event(dev, we_event, &wrqu, msg);
942#ifdef FEATURE_WLAN_ESE
943 if (eConnectionState_Associated ==
944 pHddStaCtx->conn_info.connState) {
945 if ((pRoamProfile->AuthType.authType[0] ==
946 eCSR_AUTH_TYPE_CCKM_RSN) ||
947 (pRoamProfile->AuthType.authType[0] ==
948 eCSR_AUTH_TYPE_CCKM_WPA))
949 hdd_send_new_ap_channel_info(dev, pAdapter,
950 pCsrRoamInfo);
951 }
952#endif
953 }
954}
955
956/**
957 * hdd_conn_remove_connect_info() - remove connection info
958 * @pHddStaCtx: pointer to global HDD station context
959 * @pCsrRoamInfo: pointer to roam info
960 *
961 * Return: none
962 */
963static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
964{
965 /* Remove staId, bssId and peerMacAddress */
966 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530967 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
968 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530969 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800970
971 /* Clear all security settings */
972 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
973 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
974 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
975
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530976 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
977 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800978
979 /* Set not-connected state */
980 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
981 pHddStaCtx->conn_info.proxyARPService = 0;
982
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530983 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800984}
985
986/**
987 * hdd_roam_deregister_sta() - deregister station
988 * @pAdapter: pointer to adapter
989 * @staId: station identifier
990 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530991 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800992 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530993static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800994hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
995{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530996 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800997 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
998
999 if (eConnectionState_IbssDisconnected ==
1000 pHddStaCtx->conn_info.connState) {
1001 /*
1002 * Do not set the carrier off when the last peer leaves.
1003 * We will set the carrier off while stopping the IBSS.
1004 */
1005 }
1006
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301007 qdf_status = ol_txrx_clear_peer(staId);
1008 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001009 hddLog(LOGE,
1010 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301011 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001012 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301013 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001014}
1015
1016/**
1017 * hdd_dis_connect_handler() - disconnect event handler
1018 * @pAdapter: pointer to adapter
1019 * @pRoamInfo: pointer to roam info
1020 * @roamId: roam identifier
1021 * @roamStatus: roam status
1022 * @roamResult: roam result
1023 *
1024 * This function handles disconnect event:
1025 * 1. Disable transmit queues;
1026 * 2. Clean up internal connection states and data structures;
1027 * 3. Send disconnect indication to supplicant.
1028 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301029 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001030 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301031static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001032 tCsrRoamInfo *pRoamInfo,
1033 uint32_t roamId,
1034 eRoamCmdStatus roamStatus,
1035 eCsrRoamResult roamResult)
1036{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301037 QDF_STATUS status = QDF_STATUS_SUCCESS;
1038 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001039 struct net_device *dev = pAdapter->dev;
1040 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1041 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1042 uint8_t sta_id;
1043 bool sendDisconInd = true;
1044
1045 if (dev == NULL) {
1046 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301047 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048 }
1049 /* notify apps that we can't pass traffic anymore */
1050 hddLog(LOG1, FL("Disabling queues"));
1051 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
1052 WLAN_CONTROL_PATH);
1053
1054 if (hdd_ipa_is_enabled(pHddCtx))
1055 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
1056 WLAN_STA_DISCONNECT,
1057 pHddStaCtx->conn_info.bssId.bytes);
1058
1059#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1060 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1061#endif
1062
Nirav Shah1da77682016-05-03 20:16:39 +05301063 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1064 pAdapter->sessionId,
1065 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001066
1067 /* HDD has initiated disconnect, do not send disconnect indication
1068 * to kernel. Sending disconnected event to kernel for userspace
1069 * initiated disconnect will be handled by hdd_DisConnectHandler call
1070 * to cfg80211_disconnected.
1071 */
1072 if ((eConnectionState_Disconnecting ==
1073 pHddStaCtx->conn_info.connState) ||
1074 (eConnectionState_NotConnected ==
1075 pHddStaCtx->conn_info.connState)) {
1076 hddLog(LOG1,
1077 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1078 sendDisconInd = false;
1079 }
1080
1081 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1082 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001083 hdd_conn_set_connection_state(pAdapter,
1084 eConnectionState_Disconnecting);
1085 }
1086
1087 hdd_clear_roam_profile_ie(pAdapter);
1088 hdd_wmm_init(pAdapter);
1089
1090 /* indicate 'disconnect' status to wpa_supplicant... */
1091 hdd_send_association_event(dev, pRoamInfo);
1092 /* indicate disconnected event to nl80211 */
1093 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1094 /*
1095 * Only send indication to kernel if not initiated
1096 * by kernel
1097 */
1098 if (sendDisconInd) {
1099 /*
1100 * To avoid wpa_supplicant sending "HANGED" CMD
1101 * to ICS UI.
1102 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001103 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1104 if (pRoamInfo->reasonCode ==
1105 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1106 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001107 cfg80211_disconnected(dev, pRoamInfo->
Ryan Hsua335c162016-01-21 12:12:20 -08001108 reasonCode, NULL, 0,
1109#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1110 true,
1111#endif
1112 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001113 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001114 cfg80211_disconnected(dev,
Ryan Hsua335c162016-01-21 12:12:20 -08001115 WLAN_REASON_UNSPECIFIED, NULL, 0,
1116#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1117 true,
1118#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001119 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001120 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121
1122 hdd_info("sent disconnected event to nl80211, rssi: %d",
1123 pAdapter->rssi);
1124 }
1125 /*
1126 * During the WLAN uninitialization,supplicant is stopped
1127 * before the driver so not sending the status of the
1128 * connection to supplicant.
1129 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001130 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001131#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -08001132 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001133 if (global_p2p_connection_status ==
1134 P2P_CLIENT_CONNECTED_STATE_1) {
1135 global_p2p_connection_status =
1136 P2P_CLIENT_DISCONNECTED_STATE;
1137 hddLog(LOGE,
1138 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1139 } else if (global_p2p_connection_status ==
1140 P2P_CLIENT_COMPLETED_STATE) {
1141 global_p2p_connection_status =
1142 P2P_NOT_ACTIVE;
1143 hddLog(LOGE,
1144 "[P2P State] P2P Client is removed and moved to inactive state");
1145 }
1146 }
1147#endif
1148
1149 }
1150 }
1151
1152 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001153 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001154 if (hdd_remove_beacon_filter(pAdapter) != 0)
1155 hdd_err("hdd_remove_beacon_filter() failed");
1156
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301158 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301159 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001160 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301161 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301162 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1163 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301164 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001165 }
1166 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301167 /* Clear all the peer sta register with TL. */
1168 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1169 if (0 == pHddStaCtx->conn_info.staId[i])
1170 continue;
1171 sta_id = pHddStaCtx->conn_info.staId[i];
1172 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1173 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301174 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301175 hddLog(LOGE,
1176 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1177 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301178 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301179 }
1180 /* set the staid and peer mac as 0, all other
1181 * reset are done in hdd_connRemoveConnectInfo.
1182 */
1183 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301184 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301185 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301186 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1187 pHddCtx->sta_to_adapter[sta_id] = NULL;
1188 }
1189 } else {
1190 sta_id = pHddStaCtx->conn_info.staId[0];
1191 /* We should clear all sta register with TL,
1192 * for now, only one.
1193 */
1194 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301195 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301196 hddLog(LOGE,
1197 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1198 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301199 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301200 }
1201 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001202 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 /* Clear saved connection information in HDD */
1204 hdd_conn_remove_connect_info(pHddStaCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1206#ifdef WLAN_FEATURE_GTK_OFFLOAD
Krunal Sonibe766b02016-03-10 13:00:44 -08001207 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1208 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001209 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1210 sizeof(tSirGtkOffloadParams));
1211 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1212 }
1213#endif
1214
1215#ifdef FEATURE_WLAN_TDLS
1216 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1217 wlan_hdd_tdls_disconnection_callback(pAdapter);
1218#endif
1219
Krunal Sonibe766b02016-03-10 13:00:44 -08001220 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1221 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001222 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1223 (pAdapter),
1224 pAdapter->sessionId);
1225 }
1226 /* Unblock anyone waiting for disconnect to complete */
1227 complete(&pAdapter->disconnect_comp_var);
1228 return status;
1229}
1230
1231/**
1232 * hdd_set_peer_authorized_event() - set peer_authorized_event
1233 * @vdev_id: vdevid
1234 *
1235 * Return: None
1236 */
1237void hdd_set_peer_authorized_event(uint32_t vdev_id)
1238{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301239 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240 hdd_adapter_t *adapter = NULL;
1241
1242 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1243 if (adapter == NULL) {
1244 hddLog(LOGE,
1245 "%s: Invalid vdev_id", __func__);
1246 }
1247 complete(&adapter->sta_authorized_event);
1248}
1249
1250/**
1251 * hdd_change_peer_state() - change peer state
1252 * @pAdapter: HDD adapter
1253 * @sta_state: peer state
1254 * @roam_synch_in_progress: roam synch in progress
1255 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301256 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001257 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301258QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001259 uint8_t sta_id,
1260 enum ol_txrx_peer_state sta_state,
1261 bool roam_synch_in_progress)
1262{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301263 QDF_STATUS err;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001264 uint8_t *peer_mac_addr;
Manjunathappa Prakash2593a642016-04-01 08:53:35 -07001265 struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001266 ol_txrx_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267
1268 if (!pdev) {
1269 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301270 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001271 }
1272
1273 if (sta_id >= WLAN_MAX_STA_COUNT) {
1274 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301275 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276 }
1277
1278 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1279 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301280 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001281
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001282 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1283 if (peer_mac_addr == NULL) {
1284 hddLog(LOGE, "peer mac addr is NULL");
1285 return QDF_STATUS_E_FAULT;
1286 }
1287
1288 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301289 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301291 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292 }
1293#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1294 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301295 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001296#endif
1297
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001298 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001299#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1300 /* make sure event is reset */
1301 INIT_COMPLETION(pAdapter->sta_authorized_event);
1302#endif
1303
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001304 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305 hdd_set_peer_authorized_event,
1306 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301307 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001308 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301309 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310 }
1311
Krunal Sonibe766b02016-03-10 13:00:44 -08001312 if (pAdapter->device_mode == QDF_STA_MODE ||
1313 pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001314#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
Houston Hoffman52ec6692016-04-21 16:36:45 -07001315 ol_txrx_vdev_handle vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001316 unsigned long rc;
1317
1318 /* wait for event from firmware to set the event */
1319 rc = wait_for_completion_timeout(
1320 &pAdapter->sta_authorized_event,
1321 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1322 if (!rc) {
1323 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1324 __func__);
1325 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001326 vdev = ol_txrx_get_vdev_for_peer(peer);
1327 ol_txrx_vdev_unpause(vdev,
1328 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329#endif
1330 }
1331 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301332 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001333}
1334
1335/**
1336 * hdd_roam_register_sta() - register station
1337 * @pAdapter: pointer to adapter
1338 * @pRoamInfo: pointer to roam info
1339 * @staId: station identifier
1340 * @pPeerMacAddress: peer MAC address
1341 * @pBssDesc: pointer to BSS description
1342 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301343 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301345static QDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001346 tCsrRoamInfo *pRoamInfo,
1347 uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301348 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001349 tSirBssDescription *pBssDesc)
1350{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301351 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001352 struct ol_txrx_desc_type staDesc = { 0 };
1353 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Dhanashri Atre182b0272016-02-17 15:35:07 -08001354 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355
1356 if (NULL == pBssDesc)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301357 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001358
1359 /* Get the Station ID from the one saved during the association */
1360 staDesc.sta_id = staId;
1361
1362 /* set the QoS field appropriately */
1363 if (hdd_wmm_is_active(pAdapter))
1364 staDesc.is_qos_enabled = 1;
1365 else
1366 staDesc.is_qos_enabled = 0;
1367
1368#ifdef FEATURE_WLAN_WAPI
1369 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1370 pAdapter->wapi_info.fIsWapiSta);
1371 if (pAdapter->wapi_info.fIsWapiSta)
1372 staDesc.is_wapi_supported = 1;
1373 else
1374 staDesc.is_wapi_supported = 0;
1375#endif /* FEATURE_WLAN_WAPI */
1376
Dhanashri Atre50141c52016-04-07 13:15:29 -07001377 /* Register the vdev transmit and receive functions */
1378 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
1379 txrx_ops.rx.rx = hdd_rx_packet_cbk;
1380 ol_txrx_vdev_register(
1381 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
1382 pAdapter, &txrx_ops);
1383 pAdapter->tx_fn = txrx_ops.tx.tx;
1384
Dhanashri Atre182b0272016-02-17 15:35:07 -08001385 qdf_status = ol_txrx_register_peer(&staDesc);
1386
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301387 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001388 hddLog(LOGW,
1389 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301390 qdf_status, qdf_status);
1391 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001392 }
1393
1394 if (!pRoamInfo->fAuthRequired) {
1395 /*
1396 * Connections that do not need Upper layer auth, transition
1397 * TLSHIM directly to 'Authenticated' state
1398 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301399 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001400 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001401 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001402#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1403 pRoamInfo->roamSynchInProgress
1404#else
1405 false
1406#endif
1407 );
1408
1409 hdd_conn_set_authenticated(pAdapter, true);
1410 } else {
1411 hddLog(LOG3,
1412 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1413 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301414 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001416 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001417#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1418 pRoamInfo->roamSynchInProgress
1419#else
1420 false
1421#endif
1422 );
1423 hdd_conn_set_authenticated(pAdapter, false);
1424 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301425 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001426}
1427
1428/**
1429 * hdd_send_re_assoc_event() - send reassoc event
1430 * @dev: pointer to net device
1431 * @pAdapter: pointer to adapter
1432 * @pCsrRoamInfo: pointer to roam info
1433 * @reqRsnIe: pointer to RSN Information element
1434 * @reqRsnLength: length of RSN IE
1435 *
1436 * Return: none
1437 */
1438static void hdd_send_re_assoc_event(struct net_device *dev,
1439 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1440 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1441{
1442 unsigned int len = 0;
1443 u8 *pFTAssocRsp = NULL;
1444 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001445 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 uint32_t rspRsnLength = 0;
1447 struct ieee80211_channel *chan;
1448 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1449 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1450 uint8_t *buf_ptr, ssid_ie_len;
1451 struct cfg80211_bss *bss = NULL;
1452 uint8_t *final_req_ie = NULL;
1453 tCsrRoamConnectedProfile roam_profile;
1454 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1455
1456 if (!rspRsnIe) {
1457 hddLog(LOGE, FL("Unable to allocate RSN IE"));
Naveen Rawatdafda292016-01-06 18:32:14 -08001458 goto done;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001459 }
1460
Naveen Rawat14298b92015-11-25 16:27:41 -08001461 if (!assoc_req_ies) {
1462 hdd_err("Unable to allocate Assoc Req IE");
Naveen Rawatdafda292016-01-06 18:32:14 -08001463 goto done;
Naveen Rawat14298b92015-11-25 16:27:41 -08001464 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465 if (pCsrRoamInfo == NULL) {
1466 hddLog(LOGE, FL("Invalid CSR roam info"));
1467 goto done;
1468 }
1469
1470 if (pCsrRoamInfo->nAssocRspLength == 0) {
1471 hddLog(LOGE, FL("Invalid assoc response length"));
1472 goto done;
1473 }
1474
1475 pFTAssocRsp =
1476 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1477 pCsrRoamInfo->nAssocReqLength);
1478 if (pFTAssocRsp == NULL)
1479 goto done;
1480
1481 /* pFTAssocRsp needs to point to the IEs */
1482 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1483 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1484 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1485
1486 /*
1487 * Active session count is decremented upon disconnection, but during
1488 * roaming, there is no disconnect indication and hence active session
1489 * count is not decremented.
1490 * After roaming is completed, active session count is incremented
1491 * as a part of connect indication but effectively after roaming the
1492 * active session count should still be the same and hence upon
1493 * successful reassoc decrement the active session count here.
1494 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001495 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +05301496 cds_decr_session_set_pcl(pAdapter->device_mode,
1497 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001498
1499 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1500 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1501 rspRsnLength = len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301502 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1503 qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504
1505 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1506 (int)pCsrRoamInfo->pBssDesc->channelId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301507 qdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001508 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1509 &roam_profile);
1510 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1511 pCsrRoamInfo->bssid.bytes,
1512 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
Ryan Hsu535d16a2016-01-18 16:45:12 -08001513#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001514 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
Ryan Hsu535d16a2016-01-18 16:45:12 -08001515#else
1516 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
1517#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001518
1519 if (bss == NULL)
1520 hddLog(LOGE, FL("Get BSS returned NULL"));
1521 buf_ptr = buf_ssid_ie;
1522 *buf_ptr = SIR_MAC_SSID_EID;
1523 buf_ptr++;
1524 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1525 buf_ptr++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301526 qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001527 roam_profile.SSID.length);
1528 ssid_ie_len = 2 + roam_profile.SSID.length;
Jeff Johnson9991f472016-01-06 16:02:31 -08001529 hdd_notice("SSIDIE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301530 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001531 buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1533 if (final_req_ie == NULL)
1534 goto done;
1535 buf_ptr = final_req_ie;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301536 qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 buf_ptr += ssid_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301538 qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1539 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1540 qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
Jeff Johnson9991f472016-01-06 16:02:31 -08001542 hdd_notice("Req RSN IE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301543 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001544 final_req_ie, (ssid_ie_len + reqRsnLength));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001545 cfg80211_roamed_bss(dev, bss,
1546 final_req_ie, (ssid_ie_len + reqRsnLength),
1547 rspRsnIe, rspRsnLength, GFP_KERNEL);
1548
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301549 qdf_mem_copy(assoc_req_ies,
Naveen Rawat14298b92015-11-25 16:27:41 -08001550 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1551 pCsrRoamInfo->nAssocReqLength);
1552
1553 hdd_notice("ReAssoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301554 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001555 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1556
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001557 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001558 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1559 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001560 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001561done:
Naveen Rawatdf0a7e72016-01-06 18:35:53 -08001562 sme_roam_free_connect_profile(&roam_profile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001563 if (final_req_ie)
1564 kfree(final_req_ie);
1565 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001566 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001567}
1568
1569/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301570 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001571 * @roaminfo - Roaming Information
Govind Singhedc5cda2015-10-23 17:11:35 +05301572 *
1573 * Return: roam sync status if roaming offloaded else false
1574 */
1575#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001576bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
Govind Singhedc5cda2015-10-23 17:11:35 +05301577{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001578 if (roaminfo)
1579 return roaminfo->roamSynchInProgress;
1580 else
1581 return false;
Govind Singhedc5cda2015-10-23 17:11:35 +05301582}
1583#endif
1584
1585
1586/**
1587 * hdd_change_sta_state_authenticated()-
1588 * This function changes STA state to authenticated
1589 * @adapter: pointer to the adapter structure.
1590 * @roaminfo: pointer to the RoamInfo structure.
1591 *
1592 * This is called from hdd_RoamSetKeyCompleteHandler
1593 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1594 *
1595 * Return: 0 on success and errno on failure
1596 */
1597static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1598 tCsrRoamInfo *roaminfo)
1599{
1600 int ret;
1601 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1602
1603 hddLog(LOG1,
1604 "Changing TL state to AUTHENTICATED for StaId= %d",
1605 hddstactx->conn_info.staId[0]);
1606
1607 /* Connections that do not need Upper layer authentication,
1608 * transition TL to 'Authenticated' state after the keys are set
1609 */
1610 ret = hdd_change_peer_state(adapter,
1611 hddstactx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001612 OL_TXRX_PEER_STATE_AUTH,
Govind Singhedc5cda2015-10-23 17:11:35 +05301613 hdd_is_roam_sync_in_progress(roaminfo));
1614 hdd_conn_set_authenticated(adapter, true);
Krunal Sonibe766b02016-03-10 13:00:44 -08001615 if ((QDF_STA_MODE == adapter->device_mode) ||
1616 (QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301617 sme_ps_enable_auto_ps_timer(
1618 WLAN_HDD_GET_HAL_CTX(adapter),
1619 adapter->sessionId,
1620 hddstactx->hdd_ReassocScenario);
1621 }
1622
1623 return ret;
1624}
1625
1626/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 * hdd_roam_set_key_complete_handler() - Update the security parameters
1628 * @pAdapter: pointer to adapter
1629 * @pRoamInfo: pointer to roam info
1630 * @roamId: roam id
1631 * @roamStatus: roam status
1632 * @roamResult: roam result
1633 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301634 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301636static QDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 tCsrRoamInfo *pRoamInfo,
1638 uint32_t roamId,
1639 eRoamCmdStatus roamStatus,
1640 eCsrRoamResult roamResult)
1641{
1642 eCsrEncryptionType connectedCipherAlgo;
1643 bool fConnected = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301644 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301646 tHalHandle hal_ctx = WLAN_HDD_GET_HAL_CTX(pAdapter);
1647 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1648
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001649 ENTER();
1650
1651 if (NULL == pRoamInfo) {
1652 hddLog(LOG2, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301653 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001654 }
1655 /*
1656 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1657 * then go to 'authenticated'. For all other authentication types
1658 * (those that do not require upper layer authentication) we can put TL
1659 * directly into 'authenticated' state.
1660 */
1661 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1662 MAC_ADDRESS_STR, roamStatus, roamResult,
1663 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1664
1665 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1666 &connectedCipherAlgo);
1667 if (fConnected) {
Krunal Sonibe766b02016-03-10 13:00:44 -08001668 if (QDF_IBSS_MODE == pAdapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 uint8_t staId;
1670
Anurag Chouhanc5548422016-02-24 18:33:27 +05301671 if (qdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672 pHddStaCtx->roam_info.roamingState =
1673 HDD_ROAM_STATE_NONE;
1674 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301675 qdf_status = hdd_ibss_get_sta_id(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 pHddStaCtx,
1677 &pRoamInfo->peerMac,
1678 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301679 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680 hddLog(LOG2,
1681 "WLAN TL STA Ptk Installed for STAID=%d",
1682 staId);
1683 pHddStaCtx->roam_info.roamingState =
1684 HDD_ROAM_STATE_NONE;
1685 }
1686 }
1687 } else {
1688 /*
1689 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301690 * HDD later.This routine is invoked twice.
1691 * 1)set PTK 2)set GTK.The following if
1692 * statement will be TRUE when setting GTK.
1693 * At this time we don't handle the state in detail.
1694 * Related CR: 174048 - TL not in authenticated state
1695 */
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301696 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301697 pHddStaCtx->conn_info.gtk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301698 /*
1699 * PTK exchange happens in preauthentication
1700 * itself if key_mgmt is FT-PSK, ptk_installed
1701 * was false as there is no set PTK after
1702 * roaming. STA TL state moves to authenticated
1703 * only if ptk_installed is true. So, make
1704 * ptk_installed to true in case of 11R roaming.
1705 */
1706 if (csr_neighbor_roam_is11r_assoc(mac_ctx,
1707 pAdapter->sessionId))
1708 pHddStaCtx->conn_info.ptk_installed =
1709 true;
1710 } else {
Govind Singhedc5cda2015-10-23 17:11:35 +05301711 pHddStaCtx->conn_info.ptk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301712 }
Govind Singhedc5cda2015-10-23 17:11:35 +05301713
1714 /* In WPA case move STA to authenticated when
1715 * ptk is installed.Earlier in WEP case STA
1716 * was moved to AUTHENTICATED prior to setting
1717 * the unicast key and it was resulting in sending
1718 * few un-encrypted packet. Now in WEP case
1719 * STA state will be moved to AUTHENTICATED
1720 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301722 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1723 eCSR_ENCRYPT_TYPE_WEP40) ||
1724 (pHddStaCtx->conn_info.ucEncryptionType ==
1725 eCSR_ENCRYPT_TYPE_WEP104) ||
1726 (pHddStaCtx->conn_info.ucEncryptionType ==
1727 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1728 (pHddStaCtx->conn_info.ucEncryptionType ==
1729 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1730 if (pHddStaCtx->conn_info.gtk_installed &&
1731 pHddStaCtx->conn_info.ptk_installed)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301732 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301733 hdd_change_sta_state_authenticated(pAdapter,
1734 pRoamInfo);
1735 } else if (pHddStaCtx->conn_info.ptk_installed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301736 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301737 hdd_change_sta_state_authenticated(pAdapter,
1738 pRoamInfo);
1739 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740
Govind Singhedc5cda2015-10-23 17:11:35 +05301741 if (pHddStaCtx->conn_info.gtk_installed &&
1742 pHddStaCtx->conn_info.ptk_installed) {
1743 pHddStaCtx->conn_info.gtk_installed = false;
1744 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001745 }
1746
1747 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301748 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749 }
1750 } else {
1751 /*
1752 * possible disassoc after issuing set key and waiting
1753 * set key complete.
1754 */
1755 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1756 }
1757
1758 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301759 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001760}
1761
1762/**
1763 * hdd_perform_roam_set_key_complete() - perform set key complete
1764 * @pAdapter: pointer to adapter
1765 *
1766 * Return: none
1767 */
1768void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1769{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301770 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1772 tCsrRoamInfo roamInfo;
1773 roamInfo.fAuthRequired = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301774 qdf_mem_copy(roamInfo.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301775 pHddStaCtx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301776 qdf_mem_copy(roamInfo.peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301777 pHddStaCtx->roam_info.peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301779 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001780 hdd_roam_set_key_complete_handler(pAdapter,
1781 &roamInfo,
1782 pHddStaCtx->roam_info.roamId,
1783 pHddStaCtx->roam_info.roamStatus,
1784 eCSR_ROAM_RESULT_AUTHENTICATED);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301785 if (qdf_ret_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786 hddLog(LOGE, FL("Set Key complete failure"));
1787
1788 pHddStaCtx->roam_info.deferKeyComplete = false;
1789}
1790
1791/**
1792 * hdd_association_completion_handler() - association completion handler
1793 * @pAdapter: pointer to adapter
1794 * @pRoamInfo: pointer to roam info
1795 * @roamId: roam id
1796 * @roamStatus: roam status
1797 * @roamResult: roam result
1798 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301799 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001800 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301801static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802 tCsrRoamInfo *pRoamInfo,
1803 uint32_t roamId,
1804 eRoamCmdStatus roamStatus,
1805 eCsrRoamResult roamResult)
1806{
1807 struct net_device *dev = pAdapter->dev;
1808 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1809 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301810 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001811 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1812 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001813 int ft_carrier_on = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001814 bool hddDisconInProgress = false;
1815 unsigned long rc;
1816
1817 if (!pHddCtx) {
1818 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301819 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001820 }
1821
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001822 /* HDD has initiated disconnect, do not send connect result indication
1823 * to kernel as it will be handled by __cfg80211_disconnect.
1824 */
1825 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1826 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1827 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1828 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1829 hddDisconInProgress = true;
1830 }
1831
1832 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1833 if (NULL == pRoamInfo) {
1834 hddLog(LOGE, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301835 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001836 }
1837 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001838 hdd_conn_set_connection_state(pAdapter,
1839 eConnectionState_Associated);
1840 }
1841 /* Save the connection info from CSR... */
1842 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1843 eCSR_BSS_TYPE_INFRASTRUCTURE);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001844
1845 if (hdd_add_beacon_filter(pAdapter) != 0)
1846 hdd_err("hdd_add_beacon_filter() failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001847#ifdef FEATURE_WLAN_WAPI
1848 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1849 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1850 || pRoamInfo->u.pConnectedProfile->AuthType ==
1851 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1852 pAdapter->wapi_info.fIsWapiSta = 1;
1853 } else {
1854 pAdapter->wapi_info.fIsWapiSta = 0;
1855 }
1856#endif /* FEATURE_WLAN_WAPI */
1857
1858 /* Indicate 'connect' status to user space */
1859 hdd_send_association_event(dev, pRoamInfo);
1860
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001861 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001862 if (pHddCtx->miracast_value)
1863 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1864 }
1865
1866 /* Initialize the Linkup event completion variable */
1867 INIT_COMPLETION(pAdapter->linkup_event_var);
1868
1869 /*
1870 * Sometimes Switching ON the Carrier is taking time to activate
1871 * the device properly. Before allowing any packet to go up to
1872 * the application, device activation has to be ensured for
1873 * proper queue mapping by the kernel. we have registered net
1874 * device notifier for device change notification. With this we
1875 * will come to know that the device is getting
1876 * activated properly.
1877 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001878 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001879 /*
1880 * Enable Linkup Event Servicing which allows the net
1881 * device notifier to set the linkup event variable.
1882 */
1883 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001884
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001885 /* Switch on the Carrier to activate the device */
1886 wlan_hdd_netif_queue_control(pAdapter,
1887 WLAN_NETIF_CARRIER_ON,
1888 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001889
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001890 /*
1891 * Wait for the Link to up to ensure all the queues
1892 * are set properly by the kernel.
1893 */
1894 rc = wait_for_completion_timeout(
1895 &pAdapter->linkup_event_var,
1896 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1897 );
1898 if (!rc)
1899 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001900
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001901 /*
1902 * Disable Linkup Event Servicing - no more service
1903 * required from the net device notifier call.
1904 */
1905 pAdapter->isLinkUpSvcNeeded = false;
1906 } else {
1907 pHddStaCtx->ft_carrier_on = false;
1908 ft_carrier_on = true;
1909 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1911 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1912 else
1913 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1914 pRoamInfo->staId);
1915
1916 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1917
1918 if (hdd_ipa_is_enabled(pHddCtx))
1919 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1920 WLAN_STA_CONNECT,
1921 pRoamInfo->bssid.bytes);
1922
1923#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1924 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1925#endif
1926
Chandrasekaran Manishekar068e25e2016-03-07 11:51:07 +05301927 hdd_info("check for SAP restart");
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001928 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001929 pAdapter);
1930
1931#ifdef FEATURE_WLAN_TDLS
1932 wlan_hdd_tdls_connection_callback(pAdapter);
1933#endif
1934
Nirav Shah1da77682016-05-03 20:16:39 +05301935 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1936 pAdapter->sessionId,
1937 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
1938
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001939 /*
1940 * For reassoc, the station is already registered, all we need
1941 * is to change the state of the STA in TL.
1942 * If authentication is required (WPA/WPA2/DWEP), change TL to
1943 * CONNECTED instead of AUTHENTICATED.
1944 */
1945 if (!pRoamInfo->fReassocReq) {
1946 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001947 u8 *pFTAssocRsp = NULL;
1948 unsigned int assocRsplen = 0;
1949 u8 *pFTAssocReq = NULL;
1950 unsigned int assocReqlen = 0;
1951 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001952 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1953 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1954
1955 /* add bss_id to cfg80211 data base */
1956 bss =
1957 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1958 pRoamInfo);
1959 if (NULL == bss) {
1960 pr_err("wlan: Not able to create BSS entry\n");
1961 wlan_hdd_netif_queue_control(pAdapter,
1962 WLAN_NETIF_CARRIER_OFF,
1963 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301964 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001966 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1967 eCSR_AUTH_TYPE_FT_RSN
1968 || pRoamInfo->u.pConnectedProfile->AuthType ==
1969 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1970
1971 /* Association Response */
1972 pFTAssocRsp =
1973 (u8 *) (pRoamInfo->pbFrames +
1974 pRoamInfo->nBeaconLength +
1975 pRoamInfo->nAssocReqLength);
1976 if (pFTAssocRsp != NULL) {
1977 /*
1978 * pFTAssocRsp needs to point to the IEs
1979 */
1980 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1981 hddLog(LOG1,
1982 FL("AssocRsp is now at %02x%02x"),
1983 (unsigned int)pFTAssocRsp[0],
1984 (unsigned int)pFTAssocRsp[1]);
1985 assocRsplen =
1986 pRoamInfo->nAssocRspLength -
1987 FT_ASSOC_RSP_IES_OFFSET;
1988 } else {
1989 hddLog(LOGE, FL("AssocRsp is NULL"));
1990 assocRsplen = 0;
1991 }
1992
1993 /* Association Request */
1994 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1995 pRoamInfo->nBeaconLength);
1996 if (pFTAssocReq != NULL) {
1997 if (!ft_carrier_on) {
1998 /*
1999 * pFTAssocReq needs to point to
2000 * the IEs
2001 */
2002 pFTAssocReq +=
2003 FT_ASSOC_REQ_IES_OFFSET;
2004 hddLog(LOG1,
2005 FL("pFTAssocReq is now at %02x%02x"),
2006 (unsigned int)
2007 pFTAssocReq[0],
2008 (unsigned int)
2009 pFTAssocReq[1]);
2010 assocReqlen =
2011 pRoamInfo->nAssocReqLength -
2012 FT_ASSOC_REQ_IES_OFFSET;
2013 } else {
2014 /*
2015 * This should contain only the
2016 * FTIEs
2017 */
2018 assocReqlen =
2019 pRoamInfo->nAssocReqLength;
2020 }
2021 } else {
2022 hddLog(LOGE, FL("AssocReq is NULL"));
2023 assocReqlen = 0;
2024 }
2025
2026 if (ft_carrier_on) {
2027 if (!hddDisconInProgress) {
2028 /*
2029 * After roaming is completed,
2030 * active session count is
2031 * incremented as a part of
2032 * connect indication but
2033 * effectively the active
2034 * session count should still
2035 * be the same and hence upon
2036 * successful reassoc
2037 * decrement the active session
2038 * count here.
2039 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002040 if (!hdd_is_roam_sync_in_progress
2041 (pRoamInfo))
2042 cds_decr_session_set_pcl
2043 (pAdapter->device_mode,
2044 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002045 hddLog(LOG1,
2046 FL("ft_carrier_on is %d, sending roamed indication"),
2047 ft_carrier_on);
2048 chan =
2049 ieee80211_get_channel
2050 (pAdapter->wdev.wiphy,
2051 (int)pRoamInfo->pBssDesc->
2052 channelId);
2053 hddLog(LOG1,
2054 "assocReqlen %d assocRsplen %d",
2055 assocReqlen,
2056 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08002057
2058 hdd_notice(
2059 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302060 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05302061 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302062 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002063 pFTAssocReq,
2064 assocReqlen);
2065
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002066 cfg80211_roamed(dev, chan,
2067 pRoamInfo->
2068 bssid.bytes,
2069 pFTAssocReq,
2070 assocReqlen,
2071 pFTAssocRsp,
2072 assocRsplen,
2073 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08002074 wlan_hdd_send_roam_auth_event(
2075 pHddCtx,
2076 pRoamInfo->bssid.bytes,
2077 pFTAssocReq,
2078 assocReqlen,
2079 pFTAssocRsp,
2080 assocRsplen,
2081 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002082 }
2083 if (sme_get_ftptk_state
2084 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2085 pAdapter->sessionId)) {
2086 sme_set_ftptk_state
2087 (WLAN_HDD_GET_HAL_CTX
2088 (pAdapter),
2089 pAdapter->sessionId,
2090 false);
2091 pRoamInfo->fAuthRequired =
2092 false;
2093
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302094 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002095 roam_info.bssid,
2096 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302097 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302098 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 roam_info.peerMac,
2100 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302101 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002102 pHddStaCtx->roam_info.roamId =
2103 roamId;
2104 pHddStaCtx->roam_info.
2105 roamStatus = roamStatus;
2106 pHddStaCtx->roam_info.
2107 deferKeyComplete = true;
2108 }
2109 } else if (!hddDisconInProgress) {
2110 hddLog(LOG1,
2111 FL("ft_carrier_on is %d, sending connect indication"),
2112 ft_carrier_on);
2113 cfg80211_connect_result(dev,
2114 pRoamInfo->
2115 bssid.bytes,
2116 pFTAssocReq,
2117 assocReqlen,
2118 pFTAssocRsp,
2119 assocRsplen,
2120 WLAN_STATUS_SUCCESS,
2121 GFP_KERNEL);
2122 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002123 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002124 /*
2125 * wpa supplicant expecting WPA/RSN IE in
2126 * connect result.
2127 */
2128 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2129 (pAdapter),
2130 pAdapter->sessionId,
2131 &reqRsnLength,
2132 reqRsnIe);
2133
2134 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2135 (pAdapter),
2136 pAdapter->sessionId,
2137 &rspRsnLength,
2138 rspRsnIe);
2139 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002140 if (ft_carrier_on)
2141 hdd_send_re_assoc_event(dev,
2142 pAdapter,
2143 pRoamInfo,
2144 reqRsnIe,
2145 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002146 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002147 hddLog(LOG1,
2148 FL("sending connect indication to nl80211:for bssid "
2149 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302150 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002151 MAC_ADDR_ARRAY
2152 (pRoamInfo->bssid.bytes),
2153 roamResult, roamStatus);
2154
2155 /* inform connect result to nl80211 */
2156 cfg80211_connect_result(dev,
2157 pRoamInfo->
2158 bssid.bytes,
2159 reqRsnIe,
2160 reqRsnLength,
2161 rspRsnIe,
2162 rspRsnLength,
2163 WLAN_STATUS_SUCCESS,
2164 GFP_KERNEL);
2165 }
2166 }
2167 }
2168 if (!hddDisconInProgress) {
2169 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002170 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002171 bss);
2172
2173 /*
2174 * Perform any WMM-related association
2175 * processing.
2176 */
2177 hdd_wmm_assoc(pAdapter, pRoamInfo,
2178 eCSR_BSS_TYPE_INFRASTRUCTURE);
2179
2180 /*
2181 * Start the Queue - Start tx queues before
2182 * hdd_roam_register_sta, since
2183 * hdd_roam_register_sta will flush any cached
2184 * data frames immediately.
2185 */
2186 hddLog(LOG1, FL("Enabling queues"));
2187 wlan_hdd_netif_queue_control(pAdapter,
2188 WLAN_WAKE_ALL_NETIF_QUEUE,
2189 WLAN_CONTROL_PATH);
2190
2191 /*
2192 * Register the Station with TL after associated
2193 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302194 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002195 pRoamInfo,
2196 pHddStaCtx->
2197 conn_info.
2198 staId[0],
2199 NULL,
2200 pRoamInfo->
2201 pBssDesc);
2202 }
2203 } else {
2204 /*
2205 * wpa supplicant expecting WPA/RSN IE in connect result
2206 * in case of reassociation also need to indicate it to
2207 * supplicant.
2208 */
2209 csr_roam_get_wpa_rsn_req_ie(
2210 WLAN_HDD_GET_HAL_CTX(pAdapter),
2211 pAdapter->sessionId,
2212 &reqRsnLength, reqRsnIe);
2213
2214 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2215 reqRsnIe, reqRsnLength);
2216 /* Reassoc successfully */
2217 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302218 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002219 hdd_change_peer_state(pAdapter,
2220 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002221 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002222#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2223 pRoamInfo->roamSynchInProgress
2224#else
2225 false
2226#endif
2227 );
2228 hdd_conn_set_authenticated(pAdapter, false);
2229 } else {
2230 hddLog(LOG2,
2231 FL("staId: %d Changing TL state to AUTHENTICATED"),
2232 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302233 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002234 hdd_change_peer_state(pAdapter,
2235 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002236 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2238 pRoamInfo->roamSynchInProgress
2239#else
2240 false
2241#endif
2242 );
2243 hdd_conn_set_authenticated(pAdapter, true);
2244 }
2245
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302246 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002247 /*
2248 * Perform any WMM-related association
2249 * processing
2250 */
2251 hdd_wmm_assoc(pAdapter, pRoamInfo,
2252 eCSR_BSS_TYPE_INFRASTRUCTURE);
2253 }
2254
2255 /* Start the tx queues */
2256#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2257 if (pRoamInfo->roamSynchInProgress)
2258 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2259#endif
2260 hddLog(LOG1, FL("Enabling queues"));
2261 wlan_hdd_netif_queue_control(pAdapter,
2262 WLAN_WAKE_ALL_NETIF_QUEUE,
2263 WLAN_CONTROL_PATH);
2264 }
2265
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302266 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002267 hddLog(LOGE,
2268 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302269 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002270 }
2271#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302272 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002273 sizeof(pAdapter->hdd_stats.hddPmfStats));
2274#endif
2275 } else {
2276 hdd_wext_state_t *pWextState =
2277 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2278 if (pRoamInfo)
2279 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302280 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002281 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2282 roamResult, roamStatus);
2283 else
2284 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302285 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002286 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2287 roamResult, roamStatus);
2288
2289 /*
2290 * CR465478: Only send up a connection failure result when CSR
2291 * has completed operation - with a ASSOCIATION_FAILURE status.
2292 */
2293 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2294 && !hddDisconInProgress) {
2295 if (pRoamInfo)
2296 hddLog(LOGE,
2297 FL("send connect failure to nl80211: for bssid "
2298 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302299 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002300 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302301 roamResult, roamStatus,
2302 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002303 else
2304 hddLog(LOGE,
2305 FL("connect failed: for bssid "
2306 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302307 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002308 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2309 roamResult, roamStatus);
2310
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002311 /* inform association failure event to nl80211 */
2312 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2313 roamResult) {
2314 if (pRoamInfo)
2315 cfg80211_connect_result(dev,
2316 pRoamInfo->bssid.bytes,
2317 NULL, 0, NULL, 0,
2318 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2319 GFP_KERNEL);
2320 else
2321 cfg80211_connect_result(dev,
2322 pWextState->req_bssId.bytes,
2323 NULL, 0, NULL, 0,
2324 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2325 GFP_KERNEL);
2326 } else {
2327 if (pRoamInfo) {
2328 eCsrAuthType authType =
2329 pWextState->roamProfile.AuthType.
2330 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302331 eCsrEncryptionType encryption_type =
2332 pWextState->roamProfile.
2333 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302335 (((authType ==
2336 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002337 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302338 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2339 ((encryption_type ==
2340 eCSR_ENCRYPT_TYPE_WEP40) ||
2341 (encryption_type ==
2342 eCSR_ENCRYPT_TYPE_WEP104) ||
2343 (encryption_type ==
2344 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2345 (encryption_type ==
2346 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002347 /*
2348 * In case of OPEN-WEP or SHARED-WEP
2349 * authentication, send exact protocol
2350 * reason code. This enables user
2351 * applications to reconnect the station
2352 * with correct configuration.
2353 */
2354 cfg80211_connect_result(dev,
2355 pRoamInfo->bssid.bytes, NULL, 0,
2356 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302357 (isWep &&
2358 pRoamInfo->reasonCode) ?
2359 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002360 WLAN_STATUS_UNSPECIFIED_FAILURE,
2361 GFP_KERNEL);
2362 } else
2363 cfg80211_connect_result(dev,
2364 pWextState->req_bssId.bytes,
2365 NULL, 0, NULL, 0,
2366 WLAN_STATUS_UNSPECIFIED_FAILURE,
2367 GFP_KERNEL);
2368 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302369 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002370 }
2371
2372 if (pRoamInfo) {
2373 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2374 pRoamInfo->statusCode)
2375 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2376 pRoamInfo->statusCode)
2377 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2378 pRoamInfo->statusCode)) {
2379 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2380 pRoamInfo);
2381 }
2382 }
2383
2384 /*
2385 * Set connection state to eConnectionState_NotConnected only
2386 * when CSR has completed operation - with a
2387 * ASSOCIATION_FAILURE status.
2388 */
2389 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2390 && !hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002391 hdd_conn_set_connection_state(pAdapter,
2392 eConnectionState_NotConnected);
2393 }
2394 hdd_wmm_init(pAdapter);
2395
2396 hddLog(LOG1, FL("Disabling queues"));
2397 wlan_hdd_netif_queue_control(pAdapter,
2398 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2399 WLAN_CONTROL_PATH);
2400 }
2401
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302402 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002403 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302404 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002405
Govind Singh24db1ed2015-12-18 15:54:59 +05302406 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2407 cds_force_sap_on_scc(roamResult,
2408 pRoamInfo->pBssDesc->channelId);
2409 } else {
2410 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302411 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302412 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302414 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002415}
2416
2417/**
2418 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2419 * @pAdapter: pointer to adapter
2420 * @pRoamInfo: pointer to roam info
2421 * @roamId: roam id
2422 * @roamStatus: roam status
2423 * @roamResult: roam result
2424 *
2425 * Here we update the status of the Ibss when we receive information that we
2426 * have started/joined an ibss session.
2427 *
2428 * Return: none
2429 */
2430static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2431 tCsrRoamInfo *pRoamInfo,
2432 uint32_t roamId,
2433 eRoamCmdStatus roamStatus,
2434 eCsrRoamResult roamResult)
2435{
2436 hddLog(LOG1, "%s: id %d, status %d, result %d",
2437 pAdapter->dev->name, roamId, roamStatus, roamResult);
2438
2439 switch (roamResult) {
2440 /* both IBSS Started and IBSS Join should come in here. */
2441 case eCSR_ROAM_RESULT_IBSS_STARTED:
2442 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2443 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2444 {
2445 hdd_context_t *pHddCtx =
2446 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302447 hdd_station_ctx_t *hdd_sta_ctx =
2448 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302449 struct qdf_mac_addr broadcastMacAddr =
2450 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002451
2452 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302453 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002454 return;
2455 }
2456
2457 /* When IBSS Started comes from CSR, we need to move
2458 * connection state to IBSS Disconnected (meaning no peers
2459 * are in the IBSS).
2460 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002461 hdd_conn_set_connection_state(pAdapter,
2462 eConnectionState_IbssDisconnected);
2463 /* notify wmm */
2464 hdd_wmm_connect(pAdapter, pRoamInfo,
2465 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302466
2467 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2468
2469 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002470 pAdapter;
2471 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302472 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002473 &broadcastMacAddr,
2474 pRoamInfo->pBssDesc);
2475
2476 if (pRoamInfo->pBssDesc) {
2477 struct cfg80211_bss *bss;
2478#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2479 struct ieee80211_channel *chan;
2480 int chan_no;
2481 unsigned int freq;
2482#endif
2483 /* we created the IBSS, notify supplicant */
2484 hddLog(LOG1,
2485 FL("%s: created ibss " MAC_ADDRESS_STR),
2486 pAdapter->dev->name,
2487 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2488
2489 /* we must first give cfg80211 the BSS information */
2490 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2491 pRoamInfo);
2492 if (NULL == bss) {
2493 hddLog(LOGE,
2494 FL("%s: unable to create IBSS entry"),
2495 pAdapter->dev->name);
2496 return;
2497 }
2498 hddLog(LOG1, FL("Enabling queues"));
2499 wlan_hdd_netif_queue_control(pAdapter,
2500 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2501 WLAN_CONTROL_PATH);
2502
2503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2504 chan_no = pRoamInfo->pBssDesc->channelId;
2505
2506 if (chan_no <= 14)
2507 freq = ieee80211_channel_to_frequency(chan_no,
2508 IEEE80211_BAND_2GHZ);
2509 else
2510 freq = ieee80211_channel_to_frequency(chan_no,
2511 IEEE80211_BAND_5GHZ);
2512
2513 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2514
2515 if (chan)
2516 cfg80211_ibss_joined(pAdapter->dev,
2517 bss->bssid, chan,
2518 GFP_KERNEL);
2519 else
2520 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2521 pAdapter->dev->name,
2522 (int)pRoamInfo->pBssDesc->channelId);
2523#else
2524 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2525 GFP_KERNEL);
2526#endif
2527 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002529 bss);
2530 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002531 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002532 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002533 pAdapter->sessionId);
2534 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2535 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002536 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002537 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002538 break;
2539 }
2540
2541 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2542 {
2543 hddLog(LOGE,
2544 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2545 break;
2546 }
2547
2548 default:
2549 hddLog(LOGE, FL("%s: unexpected result %d"),
2550 pAdapter->dev->name, (int)roamResult);
2551 break;
2552 }
2553
2554 return;
2555}
2556
2557/**
2558 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2559 * @pHddStaCtx: pointer to global HDD station context
2560 * @staId: station id
2561 * @peerMacAddress: pointer to peer MAC address
2562 *
2563 * This information is passed to iwconfig later. The peer that joined
2564 * last is passed as information to iwconfig.
2565 *
2566 * Return:
2567 * true if we add MAX_IBSS_PEERS or less STA
2568 * false otherwise.
2569 */
2570static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302571 struct qdf_mac_addr *peerMacAddress)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002572{
2573 bool fSuccess = false;
2574 int idx = 0;
2575
2576 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2577 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2578 pHddStaCtx->conn_info.staId[idx] = staId;
2579
Anurag Chouhanc5548422016-02-24 18:33:27 +05302580 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002581 peerMacAddress[idx], peerMacAddress);
2582
2583 fSuccess = true;
2584 break;
2585 }
2586 }
2587
2588 return fSuccess;
2589}
2590
2591/**
2592 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2593 * @pAdapter: pointer to adapter
2594 * @staId: station id
2595 *
2596 * Return:
2597 * true if we remove MAX_IBSS_PEERS or less STA
2598 * false otherwise.
2599 */
2600static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2601{
2602 bool fSuccess = false;
2603 int idx = 0;
2604 uint8_t valid_idx = 0;
2605 uint8_t del_idx = 0;
2606 uint8_t empty_slots = 0;
2607 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2608
2609 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2610 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2611 pHddStaCtx->conn_info.staId[idx] = 0;
2612
Anurag Chouhanc5548422016-02-24 18:33:27 +05302613 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614 peerMacAddress[idx]);
2615
2616 fSuccess = true;
2617
2618 /*
2619 * Note the deleted Index, if its 0 we need special
2620 * handling.
2621 */
2622 del_idx = idx;
2623
2624 empty_slots++;
2625 } else {
2626 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2627 valid_idx = idx;
2628 } else {
2629 /* Found an empty slot */
2630 empty_slots++;
2631 }
2632 }
2633 }
2634
2635 if (MAX_IBSS_PEERS == empty_slots) {
2636 /* Last peer departed, set the IBSS state appropriately */
2637 pHddStaCtx->conn_info.connState =
2638 eConnectionState_IbssDisconnected;
2639 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2640 }
2641 /* Find next active staId, to have a valid sta trigger for TL. */
2642 if (fSuccess == true) {
2643 if (del_idx == 0) {
2644 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2645 pHddStaCtx->conn_info.staId[0] =
2646 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302647 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002648 peerMacAddress[0],
2649 &pHddStaCtx->conn_info.
2650 peerMacAddress[valid_idx]);
2651
2652 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302653 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002654 peerMacAddress[valid_idx]);
2655 }
2656 }
2657 }
2658 return fSuccess;
2659}
2660
2661/**
2662 * roam_ibss_connect_handler() - IBSS connection handler
2663 * @pAdapter: pointer to adapter
2664 * @pRoamInfo: pointer to roam info
2665 *
2666 * We update the status of the IBSS to connected in this function.
2667 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302668 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302670static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002671 tCsrRoamInfo *pRoamInfo)
2672{
2673 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002674 /*
2675 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2676 * a partner stations).
2677 */
2678 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2679
2680 /* Save the connection info from CSR... */
2681 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2682
2683 /* Send the bssid address to the wext. */
2684 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2685 /* add bss_id to cfg80211 data base */
2686 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2687 if (NULL == bss) {
2688 hddLog(LOGE,
2689 FL("%s: unable to create IBSS entry"),
2690 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302691 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002692 }
2693 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002695 bss);
2696
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302697 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698}
2699
2700/**
2701 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2702 * @pAdapter: pointer to adapter
2703 * @pRoamInfo: pointer to roam info
2704 * @roamId: roam id
2705 * @roamStatus: roam status
2706 * @roamResult: roam result
2707 *
2708 * This function indicates the Mic failure to the supplicant
2709 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302710 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002711 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302712static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2714 tCsrRoamInfo *pRoamInfo,
2715 uint32_t roamId,
2716 eRoamCmdStatus roamStatus,
2717 eCsrRoamResult roamResult)
2718{
2719 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2720
2721 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2722 TKIP_COUNTER_MEASURE_STOPED ==
2723 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2724 struct iw_michaelmicfailure msg;
2725 union iwreq_data wreq;
2726 memset(&msg, '\0', sizeof(msg));
2727 msg.src_addr.sa_family = ARPHRD_ETHER;
2728 memcpy(msg.src_addr.sa_data,
2729 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2730 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2731 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2732 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2733
2734 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2735 msg.flags = IW_MICFAILURE_GROUP;
2736 else
2737 msg.flags = IW_MICFAILURE_PAIRWISE;
2738 memset(&wreq, 0, sizeof(wreq));
2739 wreq.data.length = sizeof(msg);
2740 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2741 (char *)&msg);
2742 /* inform mic failure to nl80211 */
2743 cfg80211_michael_mic_failure(pAdapter->dev,
2744 pRoamInfo->u.pMICFailureInfo->
2745 taMacAddr,
2746 ((pRoamInfo->u.pMICFailureInfo->
2747 multicast ==
2748 eSIR_TRUE) ?
2749 NL80211_KEYTYPE_GROUP :
2750 NL80211_KEYTYPE_PAIRWISE),
2751 pRoamInfo->u.pMICFailureInfo->
2752 keyId,
2753 pRoamInfo->u.pMICFailureInfo->TSC,
2754 GFP_KERNEL);
2755
2756 }
2757
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302758 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002759}
2760
2761/**
2762 * roam_roam_connect_status_update_handler() - IBSS connect status update
2763 * @pAdapter: pointer to adapter
2764 * @pRoamInfo: pointer to roam info
2765 * @roamId: roam id
2766 * @roamStatus: roam status
2767 * @roamResult: roam result
2768 *
2769 * The Ibss connection status is updated regularly here in this function.
2770 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302771 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002772 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302773static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002774roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2775 tCsrRoamInfo *pRoamInfo,
2776 uint32_t roamId,
2777 eRoamCmdStatus roamStatus,
2778 eCsrRoamResult roamResult)
2779{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302780 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002781
2782 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2783 switch (roamResult) {
2784 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2785 {
2786 hdd_station_ctx_t *pHddStaCtx =
2787 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2788 struct station_info staInfo;
2789
2790 pr_info("IBSS New Peer indication from SME "
2791 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2792 MAC_ADDRESS_STR " and stationID= %d",
2793 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2794 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2795 pRoamInfo->staId);
2796
2797 if (!roam_save_ibss_station
2798 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2799 pRoamInfo->staId,
2800 &pRoamInfo->peerMac)) {
2801 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2802 break;
2803 }
2804
2805 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2806
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002807 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302808 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002809 pRoamInfo,
2810 pRoamInfo->staId,
2811 &pRoamInfo->peerMac,
2812 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302813 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002814 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302815 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2816 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002817 }
2818 pHddStaCtx->ibss_sta_generation++;
2819 memset(&staInfo, 0, sizeof(staInfo));
2820 staInfo.filled = 0;
2821 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2822
2823 cfg80211_new_sta(pAdapter->dev,
2824 (const u8 *)pRoamInfo->peerMac.bytes,
2825 &staInfo, GFP_KERNEL);
2826
2827 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2828 pHddStaCtx->ibss_enc_key.encType
2829 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2830 pHddStaCtx->ibss_enc_key.encType
2831 || eCSR_ENCRYPT_TYPE_TKIP ==
2832 pHddStaCtx->ibss_enc_key.encType
2833 || eCSR_ENCRYPT_TYPE_AES ==
2834 pHddStaCtx->ibss_enc_key.encType) {
2835 pHddStaCtx->ibss_enc_key.keyDirection =
2836 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302837 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002838 &pRoamInfo->peerMac);
2839
2840 hddLog(LOG2, "New peer joined set PTK encType=%d",
2841 pHddStaCtx->ibss_enc_key.encType);
2842
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302843 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002844 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2845 (pAdapter),
2846 pAdapter->sessionId,
2847 &pHddStaCtx->ibss_enc_key,
2848 &roamId);
2849
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302850 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002851 hddLog(LOGE,
2852 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302853 qdf_status);
2854 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002855 }
2856 }
2857 hddLog(LOG1, FL("Enabling queues"));
2858 wlan_hdd_netif_queue_control(pAdapter,
2859 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2860 WLAN_CONTROL_PATH);
2861 break;
2862 }
2863
2864 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2865 {
2866
2867 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2868
2869 break;
2870 }
2871 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2872 {
2873 hdd_station_ctx_t *pHddStaCtx =
2874 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2875
2876 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2877 hddLog(LOGW,
2878 "IBSS peer departed by cannot find peer in our registration table with TL");
2879
2880 pr_info("IBSS Peer Departed from SME "
2881 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2882 MAC_ADDRESS_STR " and stationID= %d",
2883 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2884 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2885 pRoamInfo->staId);
2886
2887 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2888
2889 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2890 pHddStaCtx->ibss_sta_generation++;
2891
2892 cfg80211_del_sta(pAdapter->dev,
2893 (const u8 *)&pRoamInfo->peerMac.bytes,
2894 GFP_KERNEL);
2895 break;
2896 }
2897 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2898 {
2899 hddLog(LOG3,
2900 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2901 /* Stop only when we are inactive */
2902 hddLog(LOG1, FL("Disabling queues"));
2903 wlan_hdd_netif_queue_control(pAdapter,
2904 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2905 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002906 hdd_conn_set_connection_state(pAdapter,
2907 eConnectionState_NotConnected);
2908
2909 /* Send the bssid address to the wext. */
2910 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2911 break;
2912 }
2913 default:
2914 break;
2915
2916 }
2917
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302918 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002919}
2920
2921#ifdef FEATURE_WLAN_TDLS
2922/**
2923 * hdd_roam_register_tdlssta() - register new TDLS station
2924 * @pAdapter: pointer to adapter
2925 * @peerMac: pointer to peer MAC address
2926 * @staId: station identifier
2927 * @ucastSig: unicast signature
2928 *
2929 * Construct the staDesc and register with TL the new STA.
2930 * This is called as part of ADD_STA in the TDLS setup.
2931 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302932 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002933 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302934QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002935 const uint8_t *peerMac, uint16_t staId,
2936 uint8_t ucastSig)
2937{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302938 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002939 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002940 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002941
2942 /*
2943 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2944 * be peer MAC, here we are working on direct Link
2945 */
2946 staDesc.sta_id = staId;
2947
2948 /* set the QoS field appropriately .. */
2949 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2950 : (staDesc.is_qos_enabled = 0);
2951
Dhanashri Atre50141c52016-04-07 13:15:29 -07002952 /* Register the vdev transmit and receive functions */
2953 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2954 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2955 ol_txrx_vdev_register(
2956 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2957 pAdapter, &txrx_ops);
2958 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002959
2960 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002961 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302962 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002963 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302964 qdf_status, qdf_status);
2965 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002966 }
2967
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302968 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002969}
2970
2971/**
2972 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2973 * @pAdapter: pointer to adapter
2974 * @staId: station identifier
2975 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302976 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002977 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302978static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002979 uint8_t staId)
2980{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302981 QDF_STATUS qdf_status;
2982 qdf_status = ol_txrx_clear_peer(staId);
2983 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002984 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302985 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002986 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302987 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002988}
2989
2990/**
2991 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2992 * @pAdapter: pointer to adapter
2993 * @pRoamInfo: pointer to roam info
2994 * @roamId: roam id
2995 * @roamStatus: roam status
2996 * @roamResult: roam result
2997 *
2998 * HDD interface between SME and TL to ensure TDLS client registration with
2999 * TL in case of new TDLS client is added and deregistration at the time
3000 * TDLS client is deleted.
3001 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303002 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003003 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303004static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003005hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
3006 tCsrRoamInfo *pRoamInfo,
3007 uint32_t roamId,
3008 eRoamCmdStatus roamStatus,
3009 eCsrRoamResult roamResult)
3010{
3011 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3012 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
3013 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303014 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003015 uint8_t staIdx;
3016 hddTdlsPeer_t *curr_peer;
3017 uint32_t reason;
3018
3019 hddLog(LOG2,
3020 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
3021 roamResult ==
3022 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
3023 ==
3024 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
3025 roamResult ==
3026 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
3027 : roamResult ==
3028 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
3029 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
3030 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
3031 roamResult ==
3032 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
3033 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
3034 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
3035 : roamResult ==
3036 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
3037 : roamResult ==
3038 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
3039 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
3040 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
3041
3042 if (!pHddTdlsCtx) {
3043 hddLog(LOG1,
3044 FL("TDLS ctx is null, ignore roamResult (%d)"),
3045 roamResult);
3046 return status;
3047 }
3048
3049 switch (roamResult) {
3050 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
3051 {
3052 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3053 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
3054 pRoamInfo->statusCode);
3055 } else {
3056 /*
3057 * Check if there is available index for this new TDLS
3058 * STA.
3059 */
3060 for (staIdx = 0;
3061 staIdx < pHddCtx->max_num_tdls_sta;
3062 staIdx++) {
3063 if (0 ==
3064 pHddCtx->tdlsConnInfo[staIdx].
3065 staId) {
3066 pHddCtx->tdlsConnInfo[staIdx].
3067 sessionId =
3068 pRoamInfo->sessionId;
3069 pHddCtx->tdlsConnInfo[staIdx].
3070 staId = pRoamInfo->staId;
3071
3072 hddLog(LOGW,
3073 ("TDLS: STA IDX at %d is %d "
3074 "of mac "
3075 MAC_ADDRESS_STR),
3076 staIdx,
3077 pHddCtx->
3078 tdlsConnInfo[staIdx].
3079 staId,
3080 MAC_ADDR_ARRAY
3081 (pRoamInfo->peerMac.bytes));
3082
Anurag Chouhanc5548422016-02-24 18:33:27 +05303083 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003084 tdlsConnInfo
3085 [staIdx].
3086 peerMac,
3087 &pRoamInfo->
3088 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303089 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003090 break;
3091 }
3092 }
3093 if (staIdx < pHddCtx->max_num_tdls_sta) {
3094 if (-1 ==
3095 wlan_hdd_tdls_set_sta_id(pAdapter,
3096 pRoamInfo->
3097 peerMac.bytes,
3098 pRoamInfo->
3099 staId)) {
3100 hddLog(LOGE,
3101 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303102 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003103 }
3104
3105 (WLAN_HDD_GET_CTX(pAdapter))->
3106 sta_to_adapter[pRoamInfo->staId] =
3107 pAdapter;
3108 /*
3109 * store the ucast signature,
3110 * if required for further reference.
3111 */
3112
3113 wlan_hdd_tdls_set_signature(pAdapter,
3114 pRoamInfo->
3115 peerMac.bytes,
3116 pRoamInfo->
3117 ucastSig);
3118 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303119 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003120 hddLog(LOGE,
3121 FL("no available slot in conn_info. staId %d cannot be stored"),
3122 pRoamInfo->staId);
3123 }
3124 pAdapter->tdlsAddStaStatus = status;
3125 }
3126 complete(&pAdapter->tdls_add_station_comp);
3127 break;
3128 }
3129 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3130 {
3131 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3132 hddLog(LOGE,
3133 FL("Add Sta failed. status code(=%d)"),
3134 pRoamInfo->statusCode);
3135 }
3136 /* store the ucast signature which will be used later when
3137 * registering to TL
3138 */
3139 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3140 complete(&pAdapter->tdls_add_station_comp);
3141 break;
3142 }
3143 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3144 {
3145 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3146 hddLog(LOGE,
3147 FL("Link Establish Request failed. status(=%d)"),
3148 pRoamInfo->statusCode);
3149 }
3150 complete(&pAdapter->tdls_link_establish_req_comp);
3151 break;
3152 }
3153 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3154 {
3155 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3156 staIdx++) {
3157 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3158 pRoamInfo->sessionId)
3159 && pRoamInfo->staId ==
3160 pHddCtx->tdlsConnInfo[staIdx].staId) {
3161 hddLog(LOGW,
3162 ("HDD: del STA IDX = %x"),
3163 pRoamInfo->staId);
3164
3165 curr_peer =
3166 wlan_hdd_tdls_find_peer(pAdapter,
3167 pRoamInfo->
3168 peerMac.bytes,
3169 true);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303170 if (NULL != curr_peer) {
3171 hdd_info("Current status for peer " MAC_ADDRESS_STR " is %d",
3172 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3173 curr_peer->link_status);
3174 if (TDLS_IS_CONNECTED(curr_peer)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003175 hdd_roam_deregister_tdlssta
3176 (pAdapter,
3177 pRoamInfo->staId);
3178 wlan_hdd_tdls_decrement_peer_count
3179 (pAdapter);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303180 } else if (eTDLS_LINK_CONNECTING ==
3181 curr_peer->link_status) {
3182 hdd_roam_deregister_tdlssta
3183 (pAdapter,
3184 pRoamInfo->staId);
3185 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003186 }
3187 wlan_hdd_tdls_reset_peer(pAdapter,
3188 pRoamInfo->
3189 peerMac.bytes);
3190
3191 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3192 pHddCtx->tdlsConnInfo[staIdx].
3193 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303194 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003195 tdlsConnInfo[staIdx].
3196 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303197 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303198 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003199 break;
3200 }
3201 }
3202 complete(&pAdapter->tdls_del_station_comp);
3203 }
3204 break;
3205 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3206 {
3207 hddLog(LOGE,
3208 FL("Sending teardown to supplicant with reason code %u"),
3209 pRoamInfo->reasonCode);
3210
3211 curr_peer =
3212 wlan_hdd_tdls_find_peer(pAdapter,
3213 pRoamInfo->peerMac.bytes, true);
3214 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3215 pRoamInfo->reasonCode);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303216 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT,
3217 curr_peer->peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303218 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219 break;
3220 }
3221 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3222 {
3223 /* 0 staIdx is assigned to AP we dont want to touch that */
3224 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3225 staIdx++) {
3226 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3227 pRoamInfo->sessionId)
3228 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3229 hddLog(LOGW,
3230 ("hdd_tdlsStatusUpdate: staIdx %d "
3231 MAC_ADDRESS_STR),
3232 pHddCtx->tdlsConnInfo[staIdx].
3233 staId,
3234 MAC_ADDR_ARRAY(pHddCtx->
3235 tdlsConnInfo
3236 [staIdx].
3237 peerMac.
3238 bytes));
3239 wlan_hdd_tdls_reset_peer(pAdapter,
3240 pHddCtx->
3241 tdlsConnInfo
3242 [staIdx].
3243 peerMac.bytes);
3244 hdd_roam_deregister_tdlssta(pAdapter,
3245 pHddCtx->
3246 tdlsConnInfo
3247 [staIdx].
3248 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303249 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003250 sizeof
3251 (smeTdlsPeerStateParams));
3252 smeTdlsPeerStateParams.vdevId =
3253 pHddCtx->tdlsConnInfo[staIdx].
3254 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303255 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003256 peerMacAddr,
3257 &pHddCtx->
3258 tdlsConnInfo[staIdx].
3259 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303260 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003261 smeTdlsPeerStateParams.peerState =
3262 eSME_TDLS_PEER_STATE_TEARDOWN;
3263
3264 hddLog(LOG1,
3265 FL("calling sme_update_tdls_peer_state for staIdx %d "
3266 MAC_ADDRESS_STR),
3267 pHddCtx->tdlsConnInfo[staIdx].
3268 staId,
3269 MAC_ADDR_ARRAY(pHddCtx->
3270 tdlsConnInfo
3271 [staIdx].
3272 peerMac.
3273 bytes));
3274 status =
3275 sme_update_tdls_peer_state(
3276 pHddCtx->hHal,
3277 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303278 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003279 hddLog(LOGE,
3280 FL("sme_update_tdls_peer_state failed for "
3281 MAC_ADDRESS_STR),
3282 MAC_ADDR_ARRAY
3283 (pHddCtx->
3284 tdlsConnInfo[staIdx].
3285 peerMac.bytes));
3286 }
3287 wlan_hdd_tdls_decrement_peer_count
3288 (pAdapter);
3289
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303290 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003291 tdlsConnInfo[staIdx].
3292 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303293 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003294 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3295 pHddCtx->tdlsConnInfo[staIdx].
3296 sessionId = 255;
3297
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303298 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003299 }
3300 }
3301 break;
3302 }
3303 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3304 {
3305 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303306 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3307 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003308 hddLog(LOG2,
3309 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3310 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303311 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303312 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003313 break;
3314 }
3315
3316 curr_peer =
3317 wlan_hdd_tdls_get_peer(pAdapter,
3318 pRoamInfo->peerMac.bytes);
3319 if (!curr_peer) {
3320 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303321 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003322 } else {
3323 if (eTDLS_LINK_CONNECTED ==
3324 curr_peer->link_status) {
3325 hddLog(LOGE,
3326 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3327 } else {
3328 /*
3329 * If external control is enabled then initiate
3330 * TDLS only if forced peer is set otherwise
3331 * ignore should Discover trigger from fw.
3332 */
3333 if (pHddCtx->config->
3334 fTDLSExternalControl
3335 && (false ==
3336 curr_peer->isForcedPeer)) {
3337 hddLog(LOG2,
3338 FL
3339 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303340 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003341 break;
3342 } else {
3343 hddLog(LOG2,
3344 FL
3345 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3346 pHddCtx->config->
3347 fTDLSExternalControl,
3348 curr_peer->isForcedPeer,
3349 pRoamInfo->reasonCode);
3350 }
3351 wlan_hdd_tdls_pre_setup_init_work
3352 (pHddTdlsCtx, curr_peer);
3353 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303354 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003355 }
3356 break;
3357 }
3358
3359 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3360 {
3361 curr_peer =
3362 wlan_hdd_tdls_find_peer(pAdapter,
3363 pRoamInfo->peerMac.bytes, true);
3364 if (!curr_peer) {
3365 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303366 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003367 } else {
3368 if (eTDLS_LINK_CONNECTED ==
3369 curr_peer->link_status) {
3370 hddLog(LOGE,
3371 FL
3372 ("Received SHOULD_TEARDOWN for peer "
3373 MAC_ADDRESS_STR
3374 " staId: %d, reason: %d"),
3375 MAC_ADDR_ARRAY(pRoamInfo->
3376 peerMac.bytes),
3377 pRoamInfo->staId,
3378 pRoamInfo->reasonCode);
3379
3380 if (pRoamInfo->reasonCode ==
3381 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3382 pRoamInfo->reasonCode ==
3383 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3384 pRoamInfo->reasonCode ==
3385 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3386 pRoamInfo->reasonCode ==
3387 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3388 reason =
3389 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3390 } else
3391 reason =
3392 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3393
3394 wlan_hdd_tdls_indicate_teardown
3395 (pHddTdlsCtx->pAdapter, curr_peer,
3396 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303397 hdd_send_wlan_tdls_teardown_event(
3398 eTDLS_TEARDOWN_BSS_DISCONNECT,
3399 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003400 } else {
3401 hddLog(LOGE,
3402 FL
3403 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3404 pRoamInfo->reasonCode);
3405 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303406 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003407 }
3408 break;
3409 }
3410
3411 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3412 {
3413 curr_peer =
3414 wlan_hdd_tdls_find_peer(pAdapter,
3415 pRoamInfo->peerMac.bytes, true);
3416 if (!curr_peer) {
3417 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303418 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003419 } else {
3420 if (eTDLS_LINK_CONNECTED ==
3421 curr_peer->link_status) {
3422 hddLog(LOGE,
3423 FL
3424 ("Received SHOULD_PEER_DISCONNECTED for peer "
3425 MAC_ADDRESS_STR
3426 " staId: %d, reason: %d"),
3427 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3428 pRoamInfo->staId,
3429 pRoamInfo->reasonCode);
3430
3431 if (pRoamInfo->reasonCode ==
3432 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3433 pRoamInfo->reasonCode ==
3434 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3435 pRoamInfo->reasonCode ==
3436 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3437 pRoamInfo->reasonCode ==
3438 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3439 reason =
3440 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3441 } else
3442 reason =
3443 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3444
3445 wlan_hdd_tdls_indicate_teardown
3446 (pHddTdlsCtx->pAdapter, curr_peer,
3447 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303448 hdd_send_wlan_tdls_teardown_event(
3449 eTDLS_TEARDOWN_BSS_DISCONNECT,
3450 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003451 } else {
3452 hddLog(LOGE,
3453 FL
3454 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3455 pRoamInfo->reasonCode);
3456 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303457 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003458 }
3459 break;
3460 }
3461 default:
3462 {
3463 break;
3464 }
3465 }
3466
3467 return status;
3468}
3469#endif
3470
3471#ifdef WLAN_FEATURE_11W
3472/**
3473 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3474 * @pAdapter: pointer to the adapter
3475 * @nFrameLength: Length of the unprotected frame being passed
3476 * @pbFrames: Pointer to the frame buffer
3477 * @frameType: 802.11 frame type
3478 *
3479 * This function forwards the unprotected management frame to the supplicant.
3480 *
3481 * Return: nothing
3482 */
3483static void
3484hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3485 uint8_t *pbFrames, uint8_t frameType)
3486{
3487 uint8_t type = 0;
3488 uint8_t subType = 0;
3489
3490 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3491 frameType, nFrameLength);
3492
3493 /* Sanity Checks */
3494 if (NULL == pAdapter) {
3495 hddLog(LOGE, FL("pAdapter is NULL"));
3496 return;
3497 }
3498
3499 if (NULL == pAdapter->dev) {
3500 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3501 return;
3502 }
3503
3504 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3505 hddLog(LOGE, FL("pAdapter has invalid magic"));
3506 return;
3507 }
3508
3509 if (!nFrameLength) {
3510 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3511 return;
3512 }
3513
3514 if (NULL == pbFrames) {
3515 hddLog(LOGE, FL("pbFrames is NULL"));
3516 return;
3517 }
3518
3519 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3520 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3521
3522 /* Get pAdapter from Destination mac address of the frame */
3523 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3524#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3525 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3526 nFrameLength);
3527#else
3528 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3529 nFrameLength);
3530#endif
3531 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3532 } else if (type == SIR_MAC_MGMT_FRAME &&
3533 subType == SIR_MAC_MGMT_DEAUTH) {
3534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3535 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3536 nFrameLength);
3537#else
3538 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3539 nFrameLength);
3540#endif
3541 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3542 } else {
3543 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3544 type, subType);
3545 return;
3546 }
3547}
3548#endif
3549
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003550#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003551/**
3552 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3553 * @pAdapter: pointer to adapter
3554 * @tid: traffic identifier
3555 * @state: state
3556 * @measInterval: measurement interval
3557 *
3558 * This function sends traffic stream metrics IE information to
3559 * the supplicant via wireless event.
3560 *
3561 * Return: none
3562 */
3563static void
3564hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3565 uint8_t state, uint16_t measInterval)
3566{
3567 union iwreq_data wrqu;
3568 char buf[IW_CUSTOM_MAX + 1];
3569 int nBytes = 0;
3570
3571 if (NULL == pAdapter)
3572 return;
3573
3574 /* create the event */
3575 memset(&wrqu, '\0', sizeof(wrqu));
3576 memset(buf, '\0', sizeof(buf));
3577
3578 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3579 tid, state, measInterval);
3580
3581 nBytes =
3582 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3583 measInterval);
3584
3585 wrqu.data.pointer = buf;
3586 wrqu.data.length = nBytes;
3587 /* send the event */
3588 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3589}
3590
3591/**
3592 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3593 * @pAdapter: pointer to adapter
3594 * @pRoamInfo: pointer to roam info
3595 *
3596 * This function sends cckm preauth indication to the supplicant
3597 * via wireless custom event.
3598 *
3599 * Return: none
3600 */
3601static void
3602hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3603{
3604 union iwreq_data wrqu;
3605 char buf[IW_CUSTOM_MAX + 1];
3606 char *pos = buf;
3607 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3608
3609 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3610 return;
3611
3612 /* create the event */
3613 memset(&wrqu, '\0', sizeof(wrqu));
3614 memset(buf, '\0', sizeof(buf));
3615
3616 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3617 hddLog(LOG1,
3618 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3619 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3620 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3621
3622 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3623 pos += nBytes;
3624 freeBytes -= nBytes;
3625
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303626 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303627 pos += QDF_MAC_ADDR_SIZE;
3628 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003629
3630 nBytes = snprintf(pos, freeBytes, " %u:%u",
3631 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3632 freeBytes -= nBytes;
3633
3634 wrqu.data.pointer = buf;
3635 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3636
3637 /* send the event */
3638 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3639}
3640
3641/**
3642 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3643 * @pAdapter: pointer to adapter
3644 * @pRoamInfo: pointer to roam info
3645 *
3646 * Return: none
3647 */
3648static void
3649hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3650 tCsrRoamInfo *pRoamInfo)
3651{
3652 union iwreq_data wrqu;
3653 char buf[IW_CUSTOM_MAX + 1];
3654 int nBytes = 0;
3655
3656 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3657 return;
3658
3659 /* create the event */
3660 memset(&wrqu, '\0', sizeof(wrqu));
3661 memset(buf, '\0', sizeof(buf));
3662
3663 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3664
3665 nBytes =
3666 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3667 pRoamInfo->tsmRoamDelay);
3668
3669 wrqu.data.pointer = buf;
3670 wrqu.data.length = nBytes;
3671
3672 /* send the event */
3673 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3674}
3675
3676/**
3677 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3678 * @pAdapter: pointer to adapter
3679 * @measurementToken: measurement token
3680 * @flag: flag
3681 * @numBss: number of bss
3682 *
3683 * If the measurement is none and no scan results found,
3684 * indicate the supplicant about measurement done.
3685 *
3686 * Return: none
3687 */
3688void
3689hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3690 const uint16_t measurementToken,
3691 const bool flag, const uint8_t numBss)
3692{
3693 union iwreq_data wrqu;
3694 char buf[IW_CUSTOM_MAX];
3695 char *pos = buf;
3696 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3697
3698 memset(&wrqu, '\0', sizeof(wrqu));
3699 memset(buf, '\0', sizeof(buf));
3700
3701 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3702 flag, numBss);
3703
3704 nBytes =
3705 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3706 flag, numBss);
3707
3708 wrqu.data.pointer = buf;
3709 wrqu.data.length = nBytes;
3710 /* send the event */
3711 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3712}
3713
3714/**
3715 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3716 * @pAdapter: pointer to adapter
3717 * @pRoamInfo: pointer to roam info
3718 *
3719 * If the measurement is none and no scan results found,
3720 * indicate the supplicant about measurement done.
3721 *
3722 * Return: none
3723 */
3724static void
3725hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3726 const tCsrRoamInfo *pRoamInfo)
3727{
3728 union iwreq_data wrqu;
3729 char buf[IW_CUSTOM_MAX];
3730 char *pos = buf;
3731 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3732 uint8_t i = 0, len = 0;
3733 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3734 uint8_t lastSent = 0, sendBss = 0;
3735 int bcnRepFieldSize =
3736 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3737 bcnReportFields);
3738 uint8_t ieLenByte = 1;
3739 /*
3740 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3741 */
3742#define ESEBCNREPHEADER_LEN (18)
3743
3744 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3745 return;
3746
3747 /*
3748 * Custom event can pass maximum of 256 bytes of data,
3749 * based on the IE len we need to identify how many BSS info can
3750 * be filled in to custom event data.
3751 */
3752 /*
3753 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3754 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3755 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3756 */
3757
3758 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3759 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3760 hddLog(LOG1,
3761 "Measurement Done but no scan results");
3762 /* If the measurement is none and no scan results found,
3763 indicate the supplicant about measurement done */
3764 hdd_indicate_ese_bcn_report_no_results(
3765 pAdapter,
3766 pRoamInfo->pEseBcnReportRsp->
3767 measurementToken,
3768 pRoamInfo->pEseBcnReportRsp->flag,
3769 pRoamInfo->pEseBcnReportRsp->numBss);
3770 } else {
3771 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3772 memset(&wrqu, '\0', sizeof(wrqu));
3773 memset(buf, '\0', sizeof(buf));
3774 tot_bcn_ieLen = 0;
3775 sendBss = 0;
3776 pos = buf;
3777 freeBytes = IW_CUSTOM_MAX;
3778
3779 for (i = lastSent;
3780 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3781 len =
3782 bcnRepFieldSize + ieLenByte +
3783 pRoamInfo->pEseBcnReportRsp->
3784 bcnRepBssInfo[i].ieLen;
3785 if ((len + tot_bcn_ieLen) >
3786 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3787 break;
3788 }
3789 tot_bcn_ieLen += len;
3790 sendBss++;
3791 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3792 i, bcnRepFieldSize, 1,
3793 pRoamInfo->pEseBcnReportRsp->
3794 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3795 }
3796
3797 hddLog(LOG1, "Sending %d BSS Info",
3798 sendBss);
3799 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3800 pRoamInfo->pEseBcnReportRsp->measurementToken,
3801 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3802 tot_bcn_ieLen);
3803
3804 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3805 pRoamInfo->pEseBcnReportRsp->
3806 measurementToken,
3807 pRoamInfo->pEseBcnReportRsp->flag,
3808 sendBss);
3809 pos += nBytes;
3810 freeBytes -= nBytes;
3811
3812 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303813 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003814 sizeof(tot_bcn_ieLen));
3815 pos += sizeof(tot_bcn_ieLen);
3816 freeBytes -= sizeof(tot_bcn_ieLen);
3817
3818 for (i = 0; i < sendBss; i++) {
3819 hddLog(LOG1,
3820 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3821 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3822 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3823 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3824 pRoamInfo->pEseBcnReportRsp->
3825 bcnRepBssInfo[i +
3826 lastSent].bcnReportFields.
3827 ChanNum,
3828 pRoamInfo->pEseBcnReportRsp->
3829 bcnRepBssInfo[i +
3830 lastSent].bcnReportFields.
3831 Spare,
3832 pRoamInfo->pEseBcnReportRsp->
3833 bcnRepBssInfo[i +
3834 lastSent].bcnReportFields.
3835 MeasDuration,
3836 pRoamInfo->pEseBcnReportRsp->
3837 bcnRepBssInfo[i +
3838 lastSent].bcnReportFields.
3839 PhyType,
3840 pRoamInfo->pEseBcnReportRsp->
3841 bcnRepBssInfo[i +
3842 lastSent].bcnReportFields.
3843 RecvSigPower,
3844 pRoamInfo->pEseBcnReportRsp->
3845 bcnRepBssInfo[i +
3846 lastSent].bcnReportFields.
3847 ParentTsf,
3848 pRoamInfo->pEseBcnReportRsp->
3849 bcnRepBssInfo[i +
3850 lastSent].bcnReportFields.
3851 TargetTsf[0],
3852 pRoamInfo->pEseBcnReportRsp->
3853 bcnRepBssInfo[i +
3854 lastSent].bcnReportFields.
3855 TargetTsf[1],
3856 pRoamInfo->pEseBcnReportRsp->
3857 bcnRepBssInfo[i +
3858 lastSent].bcnReportFields.
3859 BcnInterval,
3860 pRoamInfo->pEseBcnReportRsp->
3861 bcnRepBssInfo[i +
3862 lastSent].bcnReportFields.
3863 CapabilityInfo,
3864 pRoamInfo->pEseBcnReportRsp->
3865 bcnRepBssInfo[i +
3866 lastSent].bcnReportFields.
3867 Bssid[0],
3868 pRoamInfo->pEseBcnReportRsp->
3869 bcnRepBssInfo[i +
3870 lastSent].bcnReportFields.
3871 Bssid[1],
3872 pRoamInfo->pEseBcnReportRsp->
3873 bcnRepBssInfo[i +
3874 lastSent].bcnReportFields.
3875 Bssid[2],
3876 pRoamInfo->pEseBcnReportRsp->
3877 bcnRepBssInfo[i +
3878 lastSent].bcnReportFields.
3879 Bssid[3],
3880 pRoamInfo->pEseBcnReportRsp->
3881 bcnRepBssInfo[i +
3882 lastSent].bcnReportFields.
3883 Bssid[4],
3884 pRoamInfo->pEseBcnReportRsp->
3885 bcnRepBssInfo[i +
3886 lastSent].bcnReportFields.
3887 Bssid[5]);
3888
3889 /* bcn report fields are copied */
3890 len =
3891 sizeof(pRoamInfo->pEseBcnReportRsp->
3892 bcnRepBssInfo[i +
3893 lastSent].
3894 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303895 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003896 (char *)&pRoamInfo->
3897 pEseBcnReportRsp->bcnRepBssInfo[i +
3898 lastSent].
3899 bcnReportFields, len);
3900 pos += len;
3901 freeBytes -= len;
3902
3903 /* Add 1 byte of ie len */
3904 len =
3905 pRoamInfo->pEseBcnReportRsp->
3906 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303907 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003908 pos += sizeof(len);
3909 freeBytes -= sizeof(len);
3910
3911 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303912 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003913 (char *)pRoamInfo->
3914 pEseBcnReportRsp->bcnRepBssInfo[i +
3915 lastSent].
3916 pBuf, len);
3917 pos += len;
3918 freeBytes -= len;
3919 }
3920
3921 wrqu.data.pointer = buf;
3922 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3923
3924 /* send the event */
3925 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3926 buf);
3927 lastSent += sendBss;
3928 }
3929 }
3930}
3931
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003932#endif /* FEATURE_WLAN_ESE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003933
3934/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303935 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
3936 * @pHddStaCtx: Station Context
3937 *
3938 * API to check if the connection authentication type is 8021x_sha256.
3939 *
3940 * Return: bool
3941 */
3942#ifdef WLAN_FEATURE_11W
3943static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3944{
3945 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
3946 pHddStaCtx->conn_info.authType;
3947}
3948#else
3949static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3950{
3951 return false;
3952}
3953#endif
3954
3955/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003956 * hdd_sme_roam_callback() - hdd sme roam callback
3957 * @pContext: pointer to adapter context
3958 * @pRoamInfo: pointer to roam info
3959 * @roamId: roam id
3960 * @roamStatus: roam status
3961 * @roamResult: roam result
3962 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303963 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003964 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303965QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003966hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3967 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3968{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303969 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003970 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3971 hdd_wext_state_t *pWextState = NULL;
3972 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303973 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003974 hdd_context_t *pHddCtx = NULL;
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05303975 struct hdd_chan_change_params chan_change;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003976
3977 hddLog(LOG2,
3978 "CSR Callback: status= %d result= %d roamID=%d",
3979 roamStatus, roamResult, roamId);
3980
3981 /* Sanity check */
3982 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3983 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303984 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003985 }
3986
3987 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3988 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3989
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303990 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05303991 pAdapter->sessionId, roamStatus));
3992
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003993 switch (roamStatus) {
3994 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05303995 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3996 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08003997 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003998 break;
3999
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004000 /*
4001 * We did pre-auth,then we attempted a 11r or ese reassoc.
4002 * reassoc failed due to failure, timeout, reject from ap
4003 * in any case tell the OS, our carrier is off and mark
4004 * interface down.
4005 */
4006 case eCSR_ROAM_FT_REASSOC_FAILED:
4007 hddLog(LOGE,
4008 FL
4009 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
4010 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304011 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004012 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4013 roamStatus, roamResult);
4014 /*
4015 * Check if Mcast/Bcast Filters are set, if yes
4016 * clear the filters here.
4017 */
4018 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
4019 true) {
4020 (WLAN_HDD_GET_CTX(pAdapter))->
4021 hdd_mcastbcast_filter_set = false;
4022 }
4023 pHddStaCtx->ft_carrier_on = false;
4024 pHddStaCtx->hdd_ReassocScenario = false;
4025 hddLog(LOG1,
4026 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
4027 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4028 break;
4029
4030 case eCSR_ROAM_FT_START:
4031 /*
4032 * When we roam for ESE and 11r, we dont want the OS to be
4033 * informed that the link is down. So mark the link ready for
4034 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
4035 * be received. Where in we will not mark the link down
4036 * Also we want to stop tx at this point when we will be
4037 * doing disassoc at this time. This saves 30-60 msec
4038 * after reassoc.
4039 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004040 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07004041 wlan_hdd_netif_queue_control(pAdapter,
4042 WLAN_NETIF_TX_DISABLE,
4043 WLAN_CONTROL_PATH);
4044 status = hdd_roam_deregister_sta(pAdapter,
4045 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304046 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304047 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004048 pHddStaCtx->ft_carrier_on = true;
4049 pHddStaCtx->hdd_ReassocScenario = true;
4050 hddLog(LOG1,
4051 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
4052 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4053 break;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07004054 case eCSR_ROAM_DISABLE_QUEUES:
4055 hdd_info("Disabling queues");
4056 wlan_hdd_netif_queue_control(pAdapter,
4057 WLAN_NETIF_TX_DISABLE,
4058 WLAN_CONTROL_PATH);
4059 break;
4060 case eCSR_ROAM_ENABLE_QUEUES:
4061 hdd_info("Enabling queues");
4062 wlan_hdd_netif_queue_control(pAdapter,
4063 WLAN_WAKE_ALL_NETIF_QUEUE,
4064 WLAN_CONTROL_PATH);
4065 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004066
4067 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004068 /* notify apps that we can't pass traffic anymore */
4069 hddLog(LOG1, FL("Disabling queues"));
4070 wlan_hdd_netif_queue_control(pAdapter,
4071 WLAN_NETIF_TX_DISABLE,
4072 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004073 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004074 wlan_hdd_netif_queue_control(pAdapter,
4075 WLAN_NETIF_CARRIER_OFF,
4076 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004077 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004078 break;
4079 case eCSR_ROAM_LOSTLINK:
4080 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
4081 hddLog(LOG2, "Roaming started due to connection lost");
4082 hddLog(LOG1, FL("Disabling queues"));
4083 wlan_hdd_netif_queue_control(pAdapter,
4084 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4085 WLAN_CONTROL_PATH);
4086 break;
4087 }
4088 case eCSR_ROAM_DISASSOCIATED:
4089 {
4090 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304091 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004092 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4093 roamStatus, roamResult);
4094 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
4095 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4096 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
4097 hdd_conf_mcastbcast_filter(pHddCtx, false);
4098
4099 if (true ==
4100 pHddCtx->sus_res_mcastbcast_filter_valid) {
4101 pHddCtx->configuredMcastBcastFilter =
4102 pHddCtx->sus_res_mcastbcast_filter;
4103 pHddCtx->
4104 sus_res_mcastbcast_filter_valid =
4105 false;
4106 }
4107
4108 hddLog(LOG1,
4109 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4110 hddLog(LOG1,
4111 "McastBcastFilter = %d",
4112 pHddCtx->configuredMcastBcastFilter);
4113 hddLog(LOG1,
4114 "offload: already called mcastbcast filter");
4115 (WLAN_HDD_GET_CTX(pAdapter))->
4116 hdd_mcastbcast_filter_set = false;
4117 }
4118 /* Call to clear any MC Addr List filter applied after
4119 * successful connection.
4120 */
4121 wlan_hdd_set_mc_addr_list(pAdapter, false);
4122 }
4123 break;
4124 case eCSR_ROAM_IBSS_LEAVE:
4125 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304126 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004127 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4128 roamStatus, roamResult);
4129 break;
4130 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4131 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4132 /*
4133 * To Do - address probable memory leak with WEP encryption upon
4134 * successful association.
4135 */
4136 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4137 /* Clear saved connection information in HDD */
4138 hdd_conn_remove_connect_info(
4139 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4140 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304141 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004142 hdd_association_completion_handler(pAdapter, pRoamInfo,
4143 roamId, roamStatus,
4144 roamResult);
4145#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4146 if (pRoamInfo)
4147 pRoamInfo->roamSynchInProgress = false;
4148#endif
4149 break;
4150 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304151 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004152 pRoamInfo,
4153 roamId,
4154 roamStatus,
4155 roamResult);
4156 break;
4157 case eCSR_ROAM_IBSS_IND:
4158 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4159 roamStatus, roamResult);
4160 break;
4161
4162 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304163 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004164 roam_roam_connect_status_update_handler(pAdapter,
4165 pRoamInfo,
4166 roamId,
4167 roamStatus,
4168 roamResult);
4169 break;
4170
4171 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304172 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004173 hdd_roam_mic_error_indication_handler(pAdapter,
4174 pRoamInfo,
4175 roamId,
4176 roamStatus,
4177 roamResult);
4178 break;
4179
4180 case eCSR_ROAM_SET_KEY_COMPLETE:
4181 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304182 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004183 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4184 roamId, roamStatus,
4185 roamResult);
4186 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4187 pHddStaCtx->hdd_ReassocScenario = false;
4188 hddLog(LOG1,
4189 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4190 pHddStaCtx->hdd_ReassocScenario,
4191 pAdapter->sessionId);
4192 }
4193 }
4194#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4195 if (pRoamInfo != NULL)
4196 pRoamInfo->roamSynchInProgress = false;
4197#endif
4198 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004199
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004200 case eCSR_ROAM_FT_RESPONSE:
4201 hdd_send_ft_event(pAdapter);
4202 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004203
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004204 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304205 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4206 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004207 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304208 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004209 wlan_hdd_cfg80211_pmksa_candidate_notify(
4210 pAdapter, pRoamInfo, 1, false);
4211 }
4212 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004213
4214#ifdef FEATURE_WLAN_LFR_METRICS
4215 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4216 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304217 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004218 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4219 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304220 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004221 }
4222 break;
4223 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4224 /*
4225 * This event will notify pre-auth completion in case of success
4226 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304227 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004228 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4229 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304230 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004231 }
4232 break;
4233 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4234 /*
4235 * This event will notify pre-auth completion incase of failure.
4236 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304237 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004238 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4239 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304240 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004241 }
4242 break;
4243 case eCSR_ROAM_HANDOVER_SUCCESS:
4244 /* This event is to notify handover success.
4245 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304246 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004247 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4248 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304249 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004250 }
4251 break;
4252#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004253 case eCSR_ROAM_REMAIN_CHAN_READY:
4254 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4255 break;
4256 case eCSR_ROAM_SEND_ACTION_CNF:
4257 hdd_send_action_cnf(pAdapter,
4258 (roamResult ==
4259 eCSR_ROAM_RESULT_NONE) ? true : false);
4260 break;
4261#ifdef FEATURE_WLAN_TDLS
4262 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304263 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004264 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4265 roamId,
4266 roamStatus,
4267 roamResult);
4268 break;
4269 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4270 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4271 pRoamInfo->reasonCode);
4272 break;
4273#endif
4274#ifdef WLAN_FEATURE_11W
4275 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4276 hdd_indicate_unprot_mgmt_frame(pAdapter,
4277 pRoamInfo->nFrameLength,
4278 pRoamInfo->pbFrames,
4279 pRoamInfo->frameType);
4280 break;
4281#endif
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004282#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004283 case eCSR_ROAM_TSM_IE_IND:
4284 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4285 pRoamInfo->tsmIe.state,
4286 pRoamInfo->tsmIe.msmt_interval);
4287 break;
4288
4289 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4290 {
4291 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4292 pHddStaCtx->conn_info.authType
4293 || eCSR_AUTH_TYPE_CCKM_RSN ==
4294 pHddStaCtx->conn_info.authType) {
4295 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4296 }
4297 break;
4298 }
4299
4300 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4301 {
4302 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4303 break;
4304 }
4305
4306 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4307 {
4308 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4309 break;
4310 }
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004311#endif /* FEATURE_WLAN_ESE */
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304312 case eCSR_ROAM_STA_CHANNEL_SWITCH:
4313 hdd_info("channel switch for session:%d to channel:%d",
4314 pAdapter->sessionId, pRoamInfo->chan_info.chan_id);
4315
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304316 chan_change.chan = pRoamInfo->chan_info.chan_id;
4317 chan_change.chan_params.ch_width =
4318 pRoamInfo->chan_info.ch_width;
4319 chan_change.chan_params.sec_ch_offset =
4320 pRoamInfo->chan_info.sec_ch_offset;
4321 chan_change.chan_params.center_freq_seg0 =
4322 pRoamInfo->chan_info.band_center_freq1;
4323 chan_change.chan_params.center_freq_seg1 =
4324 pRoamInfo->chan_info.band_center_freq2;
4325
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304326 status = hdd_chan_change_notify(pAdapter, pAdapter->dev,
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304327 chan_change);
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304328 if (QDF_IS_STATUS_ERROR(status))
4329 hdd_err("channel change notification failed");
4330
4331 status = cds_set_hw_mode_on_channel_switch(pAdapter->sessionId);
4332 if (QDF_IS_STATUS_ERROR(status))
4333 hdd_info("set hw mode change not done");
4334 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004335 default:
4336 break;
4337 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304338 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004339}
4340
4341/**
4342 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4343 * @auth_suite: auth suite
4344 *
4345 * Return: eCsrAuthType enumeration
4346 */
4347eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4348{
4349 eCsrAuthType auth_type;
4350 /* is the auth type supported? */
4351 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4352 auth_type = eCSR_AUTH_TYPE_RSN;
4353 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4354 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004355 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004356 /* Check for 11r FT Authentication with PSK */
4357 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4358 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4359 /* Check for 11R FT Authentication with 802.1X */
4360 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4361 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004362#ifdef FEATURE_WLAN_ESE
4363 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4364 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4365 } else
4366#endif /* FEATURE_WLAN_ESE */
4367#ifdef WLAN_FEATURE_11W
4368 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4369 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4370 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4371 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4372 } else
4373#endif
4374 {
4375 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4376 }
4377 return auth_type;
4378}
4379
4380/**
4381 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4382 * @auth_suite: auth suite
4383 *
4384 * Return: eCsrAuthType enumeration
4385 */
4386eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4387{
4388 eCsrAuthType auth_type;
4389 /* is the auth type supported? */
4390 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4391 auth_type = eCSR_AUTH_TYPE_WPA;
4392 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4393 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4394 } else
4395#ifdef FEATURE_WLAN_ESE
4396 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4397 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4398 } else
4399#endif /* FEATURE_WLAN_ESE */
4400 {
4401 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4402 }
4403 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4404 return auth_type;
4405}
4406
4407/**
4408 * hdd_translate_rsn_to_csr_encryption_type() -
4409 * Translate RSN to CSR encryption type
4410 * @cipher_suite: cipher suite
4411 *
4412 * Return: eCsrEncryptionType enumeration
4413 */
4414eCsrEncryptionType
4415hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4416{
4417 eCsrEncryptionType cipher_type;
4418
4419 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4420 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4421 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4422 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4423 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4424 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4425 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4426 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4427 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4428 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4429 else
4430 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4431
4432 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4433 return cipher_type;
4434}
4435
4436/**
4437 * hdd_translate_wpa_to_csr_encryption_type() -
4438 * Translate WPA to CSR encryption type
4439 * @cipher_suite: cipher suite
4440 *
4441 * Return: eCsrEncryptionType enumeration
4442 */
4443eCsrEncryptionType
4444hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4445{
4446 eCsrEncryptionType cipher_type;
4447
4448 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4449 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4450 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4451 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4452 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4453 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4454 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4455 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4456 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4457 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4458 else
4459 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4460
4461 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4462 return cipher_type;
4463}
4464
4465/**
4466 * hdd_process_genie() - process gen ie
4467 * @pAdapter: pointer to adapter
4468 * @bssid: pointer to mac address
4469 * @pEncryptType: pointer to encryption type
4470 * @mcEncryptType: pointer to multicast encryption type
4471 * @pAuthType: pointer to auth type
4472 *
4473 * Return: 0 on success, error number otherwise
4474 */
4475static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4476 u8 *bssid,
4477 eCsrEncryptionType *pEncryptType,
4478 eCsrEncryptionType *mcEncryptType,
4479 eCsrAuthType *pAuthType,
4480#ifdef WLAN_FEATURE_11W
4481 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4482#endif
4483 uint16_t gen_ie_len, uint8_t *gen_ie)
4484{
4485 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304486 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004487 tDot11fIERSN dot11RSNIE;
4488 tDot11fIEWPA dot11WPAIE;
4489 uint32_t i;
4490 uint8_t *pRsnIe;
4491 uint16_t RSNIeLen;
4492 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4493 bool updatePMKCache = false;
4494
4495 /*
4496 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4497 * setting present flag to 0.
4498 */
4499 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4500 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4501
4502 /* Type check */
4503 if (gen_ie[0] == DOT11F_EID_RSN) {
4504 /* Validity checks */
4505 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4506 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4507 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4508 gen_ie_len);
4509 return -EINVAL;
4510 }
4511 /* Skip past the EID byte and length byte */
4512 pRsnIe = gen_ie + 2;
4513 RSNIeLen = gen_ie_len - 2;
4514 /* Unpack the RSN IE */
4515 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4516 pRsnIe, RSNIeLen, &dot11RSNIE);
4517 /* Copy out the encryption and authentication types */
4518 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4519 dot11RSNIE.pwise_cipher_suite_count);
4520 hddLog(LOG1, FL("authentication suite count: %d"),
4521 dot11RSNIE.akm_suite_count);
4522 /*Here we have followed the apple base code,
4523 but probably I suspect we can do something different */
4524 /* dot11RSNIE.akm_suite_count */
4525 /* Just translate the FIRST one */
4526 *pAuthType =
4527 hdd_translate_rsn_to_csr_auth_type(
4528 dot11RSNIE.akm_suites[0]);
4529 /* dot11RSNIE.pwise_cipher_suite_count */
4530 *pEncryptType =
4531 hdd_translate_rsn_to_csr_encryption_type(
4532 dot11RSNIE.pwise_cipher_suites[0]);
4533 /* dot11RSNIE.gp_cipher_suite_count */
4534 *mcEncryptType =
4535 hdd_translate_rsn_to_csr_encryption_type(
4536 dot11RSNIE.gp_cipher_suite);
4537#ifdef WLAN_FEATURE_11W
4538 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4539 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4540#endif
4541 /* Set the PMKSA ID Cache for this interface */
4542 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4543 if (is_zero_ether_addr(bssid)) {
4544 hddLog(LOGE, FL("MAC address is all zeroes"));
4545 break;
4546 }
4547 updatePMKCache = true;
4548 /*
4549 * For right now, I assume setASSOCIATE() has passed
4550 * in the bssid.
4551 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304552 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304553 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304554 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004555 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4556 }
4557
4558 if (updatePMKCache) {
4559 /*
4560 * Calling csr_roam_set_pmkid_cache to configure the
4561 * PMKIDs into the cache.
4562 */
4563 hddLog(LOG1,
4564 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4565 i);
4566 /* Finally set the PMKSA ID Cache in CSR */
4567 result =
4568 sme_roam_set_pmkid_cache(halHandle,
4569 pAdapter->sessionId,
4570 PMKIDCache,
4571 dot11RSNIE.pmkid_count,
4572 false);
4573 }
4574 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4575 /* Validity checks */
4576 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4577 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4578 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4579 gen_ie_len);
4580 return -EINVAL;
4581 }
4582 /* Skip past the EID and length byte - and four byte WiFi OUI */
4583 pRsnIe = gen_ie + 2 + 4;
4584 RSNIeLen = gen_ie_len - (2 + 4);
4585 /* Unpack the WPA IE */
4586 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4587 pRsnIe, RSNIeLen, &dot11WPAIE);
4588 /* Copy out the encryption and authentication types */
4589 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4590 dot11WPAIE.unicast_cipher_count);
4591 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4592 dot11WPAIE.auth_suite_count);
4593 /* dot11WPAIE.auth_suite_count */
4594 /* Just translate the FIRST one */
4595 *pAuthType =
4596 hdd_translate_wpa_to_csr_auth_type(
4597 dot11WPAIE.auth_suites[0]);
4598 /* dot11WPAIE.unicast_cipher_count */
4599 *pEncryptType =
4600 hdd_translate_wpa_to_csr_encryption_type(
4601 dot11WPAIE.unicast_ciphers[0]);
4602 /* dot11WPAIE.unicast_cipher_count */
4603 *mcEncryptType =
4604 hdd_translate_wpa_to_csr_encryption_type(
4605 dot11WPAIE.multicast_cipher);
4606 } else {
4607 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4608 return -EINVAL;
4609 }
4610 return 0;
4611}
4612
4613/**
4614 * hdd_set_genie_to_csr() - set genie to csr
4615 * @pAdapter: pointer to adapter
4616 * @RSNAuthType: pointer to auth type
4617 *
4618 * Return: 0 on success, error number otherwise
4619 */
4620int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4621{
4622 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4623 uint32_t status = 0;
4624 eCsrEncryptionType RSNEncryptType;
4625 eCsrEncryptionType mcRSNEncryptType;
4626#ifdef WLAN_FEATURE_11W
4627 uint8_t RSNMfpRequired = 0;
4628 uint8_t RSNMfpCapable = 0;
4629#endif
4630 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4631 /* MAC address of assoc peer */
4632 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304633 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004634 pWextState->roamProfile.BSSIDs.bssid,
4635 sizeof(bssid));
4636 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4637 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4638 /* continue */
4639 } else {
4640 return 0;
4641 }
4642 /* The actual processing may eventually be more extensive than this. */
4643 /* Right now, just consume any PMKIDs that are sent in by the app. */
4644 status = hdd_process_genie(pAdapter, bssid,
4645 &RSNEncryptType,
4646 &mcRSNEncryptType, RSNAuthType,
4647#ifdef WLAN_FEATURE_11W
4648 &RSNMfpRequired, &RSNMfpCapable,
4649#endif
4650 pWextState->WPARSNIE[1] + 2,
4651 pWextState->WPARSNIE);
4652 if (status == 0) {
4653 /*
4654 * Now copy over all the security attributes
4655 * you have parsed out.
4656 */
4657 pWextState->roamProfile.EncryptionType.numEntries = 1;
4658 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4659
4660 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4661 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4662 mcRSNEncryptType;
4663
Krunal Sonibe766b02016-03-10 13:00:44 -08004664 if ((QDF_IBSS_MODE == pAdapter->device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004665 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4666 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4667 /*
4668 * For wpa none supplicant sends the WPA IE with unicast
4669 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4670 * multicast cipher as either AES/TKIP based on group
4671 * cipher configuration mentioned in the
4672 * wpa_supplicant.conf.
4673 */
4674
4675 /* Set the unicast cipher same as multicast cipher */
4676 pWextState->roamProfile.EncryptionType.encryptionType[0]
4677 = mcRSNEncryptType;
4678 }
4679#ifdef WLAN_FEATURE_11W
4680 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4681 RSNMfpRequired, RSNMfpCapable);
4682 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4683 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4684#endif
4685 hddLog(LOG1,
4686 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4687 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4688 }
4689 return 0;
4690}
4691
4692/**
4693 * hdd_set_csr_auth_type() - set csr auth type
4694 * @pAdapter: pointer to adapter
4695 * @RSNAuthType: auth type
4696 *
4697 * Return: 0 on success, error number otherwise
4698 */
4699int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4700{
4701 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4702 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4703 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004704
4705 pRoamProfile->AuthType.numEntries = 1;
4706 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4707 pHddStaCtx->conn_info.authType);
4708
4709 switch (pHddStaCtx->conn_info.authType) {
4710 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4711#ifdef FEATURE_WLAN_ESE
4712 case eCSR_AUTH_TYPE_CCKM_WPA:
4713 case eCSR_AUTH_TYPE_CCKM_RSN:
4714#endif
4715 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4716
4717 pRoamProfile->AuthType.authType[0] =
4718 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4719 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4720
4721#ifdef FEATURE_WLAN_ESE
4722 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4723 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4724 == IW_AUTH_KEY_MGMT_802_1X)) {
4725 hddLog(LOG1,
4726 FL("set authType to CCKM WPA. AKM also 802.1X."));
4727 pRoamProfile->AuthType.authType[0] =
4728 eCSR_AUTH_TYPE_CCKM_WPA;
4729 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4730 hddLog(LOG1,
4731 FL("Last chance to set authType to CCKM WPA."));
4732 pRoamProfile->AuthType.authType[0] =
4733 eCSR_AUTH_TYPE_CCKM_WPA;
4734 } else
4735#endif
4736 if ((pWextState->
4737 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4738 == IW_AUTH_KEY_MGMT_802_1X) {
4739 pRoamProfile->AuthType.authType[0] =
4740 eCSR_AUTH_TYPE_WPA;
4741 } else
4742 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4743 == IW_AUTH_KEY_MGMT_PSK) {
4744 pRoamProfile->AuthType.authType[0] =
4745 eCSR_AUTH_TYPE_WPA_PSK;
4746 } else {
4747 pRoamProfile->AuthType.authType[0] =
4748 eCSR_AUTH_TYPE_WPA_NONE;
4749 }
4750 }
4751 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4752#ifdef FEATURE_WLAN_ESE
4753 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4754 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4755 == IW_AUTH_KEY_MGMT_802_1X)) {
4756 hddLog(LOG1,
4757 FL("set authType to CCKM RSN. AKM also 802.1X."));
4758 pRoamProfile->AuthType.authType[0] =
4759 eCSR_AUTH_TYPE_CCKM_RSN;
4760 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4761 hddLog(LOG1,
4762 FL("Last chance to set authType to CCKM RSN."));
4763 pRoamProfile->AuthType.authType[0] =
4764 eCSR_AUTH_TYPE_CCKM_RSN;
4765 } else
4766#endif
4767
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004768 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4769 ((pWextState->
4770 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4771 == IW_AUTH_KEY_MGMT_802_1X)) {
4772 pRoamProfile->AuthType.authType[0] =
4773 eCSR_AUTH_TYPE_FT_RSN;
4774 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4775 &&
4776 ((pWextState->
4777 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4778 == IW_AUTH_KEY_MGMT_PSK)) {
4779 pRoamProfile->AuthType.authType[0] =
4780 eCSR_AUTH_TYPE_FT_RSN_PSK;
4781 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004782
4783#ifdef WLAN_FEATURE_11W
4784 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4785 pRoamProfile->AuthType.authType[0] =
4786 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4787 } else if (RSNAuthType ==
4788 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4789 pRoamProfile->AuthType.authType[0] =
4790 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4791 } else
4792#endif
4793
4794 if ((pWextState->
4795 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4796 == IW_AUTH_KEY_MGMT_802_1X) {
4797 pRoamProfile->AuthType.authType[0] =
4798 eCSR_AUTH_TYPE_RSN;
4799 } else
4800 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4801 == IW_AUTH_KEY_MGMT_PSK) {
4802 pRoamProfile->AuthType.authType[0] =
4803 eCSR_AUTH_TYPE_RSN_PSK;
4804 } else {
4805 pRoamProfile->AuthType.authType[0] =
4806 eCSR_AUTH_TYPE_UNKNOWN;
4807 }
4808 }
4809 break;
4810
4811 case eCSR_AUTH_TYPE_SHARED_KEY:
4812
4813 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4814 break;
4815 default:
4816
4817#ifdef FEATURE_WLAN_ESE
4818 hddLog(LOG1, FL("In default, unknown auth type."));
4819#endif /* FEATURE_WLAN_ESE */
4820 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4821 break;
4822 }
4823
4824 hddLog(LOG1, FL("Set roam Authtype to %d"),
4825 pWextState->roamProfile.AuthType.authType[0]);
4826
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004827 return 0;
4828}
4829
4830/**
4831 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4832 * to the CSR roam profile.
4833 *
4834 * @dev: Pointer to the net device.
4835 * @info: Pointer to the iw_request_info.
4836 * @wrqu: Pointer to the iwreq_data.
4837 * @extra: Pointer to the data.
4838 *
4839 * Return: 0 for success, error number on failure
4840 */
4841static int __iw_set_essid(struct net_device *dev,
4842 struct iw_request_info *info,
4843 union iwreq_data *wrqu, char *extra)
4844{
4845 unsigned long rc;
4846 uint32_t status = 0;
4847 hdd_wext_state_t *pWextState;
4848 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4849 hdd_context_t *hdd_ctx;
4850 uint32_t roamId;
4851 tCsrRoamProfile *pRoamProfile;
4852 eMib_dot11DesiredBssType connectedBssType;
4853 eCsrAuthType RSNAuthType;
4854 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4855 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4856 int ret;
4857
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004858 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004859
4860 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4861 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304862 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004863 return ret;
4864
Krunal Sonibe766b02016-03-10 13:00:44 -08004865 if (pAdapter->device_mode != QDF_STA_MODE &&
4866 pAdapter->device_mode != QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004867 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4868 hdd_device_mode_to_string(pAdapter->device_mode),
4869 pAdapter->device_mode);
4870 return -EINVAL;
4871 }
4872
4873 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4874
4875 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4876 hddLog(LOG2, FL("Counter measure is in progress"));
4877 return -EBUSY;
4878 }
4879 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4880 return -EINVAL;
4881
4882 pRoamProfile = &pWextState->roamProfile;
4883 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4884 (eMib_dot11DesiredBssType_independent ==
4885 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304886 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004887
4888 /* Need to issue a disconnect to CSR. */
4889 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304890 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004891 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4892
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304893 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004894 rc = wait_for_completion_timeout(&pAdapter->
4895 disconnect_comp_var,
4896 msecs_to_jiffies
4897 (WLAN_WAIT_TIME_DISCONNECT));
4898 if (!rc)
4899 hddLog(LOGE, FL("Disconnect event timed out"));
4900 }
4901 }
4902
4903 /*
4904 * when cfg80211 defined, wpa_supplicant wext driver uses
4905 * zero-length, null-string ssid for force disconnection.
4906 * after disconnection (if previously connected) and cleaning ssid,
4907 * driver MUST return success.
4908 */
4909 if (0 == wrqu->essid.length)
4910 return 0;
4911
4912 status = hdd_wmm_get_uapsd_mask(pAdapter,
4913 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304914 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004915 pWextState->roamProfile.uapsd_mask = 0;
4916
4917 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4918
4919 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4920 wrqu->essid.length;
4921
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304922 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004923 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304924 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004925 ssId), extra, wrqu->essid.length);
4926 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4927 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4928
4929 /* set gen ie */
4930 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4931
4932 /* set auth */
4933 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4934 }
4935#ifdef FEATURE_WLAN_WAPI
4936 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4937 if (pAdapter->wapi_info.nWapiMode) {
4938 switch (pAdapter->wapi_info.wapiAuthMode) {
4939 case WAPI_AUTH_MODE_PSK:
4940 {
4941 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4942 pAdapter->wapi_info.wapiAuthMode);
4943 pRoamProfile->AuthType.numEntries = 1;
4944 pRoamProfile->AuthType.authType[0] =
4945 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4946 break;
4947 }
4948 case WAPI_AUTH_MODE_CERT:
4949 {
4950 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4951 pAdapter->wapi_info.wapiAuthMode);
4952 pRoamProfile->AuthType.numEntries = 1;
4953 pRoamProfile->AuthType.authType[0] =
4954 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4955 break;
4956 }
4957 } /* End of switch */
4958 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4959 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4960 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4961 pRoamProfile->EncryptionType.numEntries = 1;
4962 pRoamProfile->EncryptionType.encryptionType[0] =
4963 eCSR_ENCRYPT_TYPE_WPI;
4964 pRoamProfile->mcEncryptionType.numEntries = 1;
4965 pRoamProfile->mcEncryptionType.encryptionType[0] =
4966 eCSR_ENCRYPT_TYPE_WPI;
4967 }
4968 }
4969#endif /* FEATURE_WLAN_WAPI */
4970 /* if previous genIE is not NULL, update AssocIE */
4971 if (0 != pWextState->genIE.length) {
4972 memset(&pWextState->assocAddIE, 0,
4973 sizeof(pWextState->assocAddIE));
4974 memcpy(pWextState->assocAddIE.addIEdata,
4975 pWextState->genIE.addIEdata, pWextState->genIE.length);
4976 pWextState->assocAddIE.length = pWextState->genIE.length;
4977 pWextState->roamProfile.pAddIEAssoc =
4978 pWextState->assocAddIE.addIEdata;
4979 pWextState->roamProfile.nAddIEAssocLength =
4980 pWextState->assocAddIE.length;
4981
4982 /* clear previous genIE after use it */
4983 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4984 }
4985
4986 /*
4987 * Assumes it is not WPS Association by default, except when
4988 * pAddIEAssoc has WPS IE.
4989 */
4990 pWextState->roamProfile.bWPSAssociation = false;
4991
4992 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4993 pWextState->roamProfile.
4994 nAddIEAssocLength))
4995 pWextState->roamProfile.bWPSAssociation = true;
4996
4997 /* Disable auto BMPS entry by PMC until DHCP is done */
4998 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
4999 true);
5000
5001 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
5002
5003 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
5004 hdd_select_cbmode(pAdapter,
5005 (WLAN_HDD_GET_CTX(pAdapter))->config->
5006 AdHocChannel5G);
5007 }
Agrawal Ashish6b015762016-05-05 11:22:18 +05305008 /*
5009 * Change conn_state to connecting before sme_roam_connect(),
5010 * because sme_roam_connect() has a direct path to call
5011 * hdd_sme_roam_callback(), which will change the conn_state
5012 * If direct path, conn_state will be accordingly changed to
5013 * NotConnected or Associated by either
5014 * hdd_association_completion_handler() or hdd_dis_connect_handler()
5015 * in sme_RoamCallback()if sme_RomConnect is to be queued,
5016 * Connecting state will remain until it is completed.
5017 *
5018 * If connection state is not changed,
5019 * connection state will remain in eConnectionState_NotConnected state.
5020 * In hdd_association_completion_handler, "hddDisconInProgress" is
5021 * set to true if conn state is eConnectionState_NotConnected.
5022 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
5023 * informed of connect result indication which is an issue.
5024 */
5025 if (QDF_STA_MODE == pAdapter->device_mode ||
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305026 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)
Agrawal Ashish6b015762016-05-05 11:22:18 +05305027 hdd_conn_set_connection_state(pAdapter,
5028 eConnectionState_Connecting);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305029
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005030 status = sme_roam_connect(hHal, pAdapter->sessionId,
5031 &(pWextState->roamProfile), &roamId);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305032 if ((QDF_STATUS_SUCCESS != status) &&
5033 (QDF_STA_MODE == pAdapter->device_mode ||
5034 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
5035 hdd_err("sme_roam_connect (session %d) failed with status %d. -> NotConnected",
5036 pAdapter->sessionId, status);
5037 /* change back to NotAssociated */
5038 hdd_conn_set_connection_state(pAdapter,
5039 eConnectionState_NotConnected);
5040 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005041 pRoamProfile->ChannelInfo.ChannelList = NULL;
5042 pRoamProfile->ChannelInfo.numOfChannels = 0;
5043
5044 EXIT();
5045 return status;
5046}
5047
5048/**
5049 * iw_set_essid() - set essid handler function
5050 * @dev: Pointer to the net device.
5051 * @info: Pointer to the iw_request_info.
5052 * @wrqu: Pointer to the iwreq_data.
5053 * @extra: Pointer to the data.
5054 *
5055 * Return: 0 for success, error number on failure
5056 */
5057int iw_set_essid(struct net_device *dev,
5058 struct iw_request_info *info,
5059 union iwreq_data *wrqu, char *extra)
5060{
5061 int ret;
5062
5063 cds_ssr_protect(__func__);
5064 ret = __iw_set_essid(dev, info, wrqu, extra);
5065 cds_ssr_unprotect(__func__);
5066
5067 return ret;
5068}
5069
5070/**
5071 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
5072 * @dev: pointer to the net device
5073 * @info: pointer to the iw request info
5074 * @dwrq: pointer to iw_point
5075 * @extra: pointer to the data
5076 *
5077 * Return: 0 on success, error number otherwise
5078 */
5079static int __iw_get_essid(struct net_device *dev,
5080 struct iw_request_info *info,
5081 struct iw_point *dwrq, char *extra)
5082{
5083 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5084 hdd_context_t *hdd_ctx;
5085 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5086 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5087 int ret;
5088
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005089 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005090
5091 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5092 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305093 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005094 return ret;
5095
5096 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
5097 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
5098 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
5099 || pHddStaCtx->conn_info.connState ==
5100 eConnectionState_IbssDisconnected)
5101 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
5102 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
5103 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
5104 dwrq->length);
5105 dwrq->flags = 1;
5106 } else {
5107 memset(extra, 0, dwrq->length);
5108 dwrq->length = 0;
5109 dwrq->flags = 0;
5110 }
5111 EXIT();
5112 return 0;
5113}
5114
5115/**
5116 * iw_get_essid() - get essid handler function
5117 * @dev: Pointer to the net device.
5118 * @info: Pointer to the iw_request_info.
5119 * @wrqu: Pointer to the iwreq_data.
5120 * @extra: Pointer to the data.
5121 *
5122 * Return: 0 for success, error number on failure
5123 */
5124int iw_get_essid(struct net_device *dev,
5125 struct iw_request_info *info,
5126 struct iw_point *wrqu, char *extra)
5127{
5128 int ret;
5129
5130 cds_ssr_protect(__func__);
5131 ret = __iw_get_essid(dev, info, wrqu, extra);
5132 cds_ssr_unprotect(__func__);
5133
5134 return ret;
5135}
5136
5137/**
5138 * __iw_set_auth() -
5139 * This function sets the auth type received from the wpa_supplicant
5140 * @dev: pointer to the net device
5141 * @info: pointer to the iw request info
5142 * @wrqu: pointer to iwreq_data
5143 * @extra: pointer to the data
5144 *
5145 * Return: 0 on success, error number otherwise
5146 */
5147static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5148 union iwreq_data *wrqu, char *extra)
5149{
5150 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5151 hdd_context_t *hdd_ctx;
5152 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5153 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5154 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5155 eCsrEncryptionType mcEncryptionType;
5156 eCsrEncryptionType ucEncryptionType;
5157 int ret;
5158
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005159 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005160
5161 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5162 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305163 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005164 return ret;
5165
5166 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5167 case IW_AUTH_WPA_VERSION:
5168 pWextState->wpaVersion = wrqu->param.value;
5169 break;
5170
5171 case IW_AUTH_CIPHER_PAIRWISE:
5172 {
5173 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5174 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5175 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5176 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5177 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5178 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5179 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5180 if ((IW_AUTH_KEY_MGMT_802_1X
5181 ==
5182 (pWextState->
5183 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5184 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5185 pHddStaCtx->conn_info.authType))
5186 /*Dynamic WEP key */
5187 ucEncryptionType =
5188 eCSR_ENCRYPT_TYPE_WEP40;
5189 else
5190 /*Static WEP key */
5191 ucEncryptionType =
5192 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5193 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5194 if ((IW_AUTH_KEY_MGMT_802_1X
5195 ==
5196 (pWextState->
5197 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5198 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5199 pHddStaCtx->conn_info.authType))
5200 /*Dynamic WEP key */
5201 ucEncryptionType =
5202 eCSR_ENCRYPT_TYPE_WEP104;
5203 else
5204 /*Static WEP key */
5205 ucEncryptionType =
5206 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5207 } else {
5208 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5209 wrqu->param.value);
5210 return -EINVAL;
5211 }
5212
5213 pRoamProfile->EncryptionType.numEntries = 1;
5214 pRoamProfile->EncryptionType.encryptionType[0] =
5215 ucEncryptionType;
5216 }
5217 break;
5218 case IW_AUTH_CIPHER_GROUP:
5219 {
5220 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5221 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5222 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5223 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5224 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5225 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5226 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5227 if ((IW_AUTH_KEY_MGMT_802_1X
5228 ==
5229 (pWextState->
5230 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5231 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5232 pHddStaCtx->conn_info.authType))
5233 mcEncryptionType =
5234 eCSR_ENCRYPT_TYPE_WEP40;
5235 else
5236 mcEncryptionType =
5237 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5238 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5239 /* Dynamic WEP keys won't work with shared keys */
5240 if ((IW_AUTH_KEY_MGMT_802_1X
5241 ==
5242 (pWextState->
5243 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5244 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5245 pHddStaCtx->conn_info.authType)) {
5246 mcEncryptionType =
5247 eCSR_ENCRYPT_TYPE_WEP104;
5248 } else {
5249 mcEncryptionType =
5250 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5251 }
5252 } else {
5253 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5254 wrqu->param.value);
5255 return -EINVAL;
5256 }
5257
5258 pRoamProfile->mcEncryptionType.numEntries = 1;
5259 pRoamProfile->mcEncryptionType.encryptionType[0] =
5260 mcEncryptionType;
5261 }
5262 break;
5263
5264 case IW_AUTH_80211_AUTH_ALG:
5265 {
5266 /* Save the auth algo here and set auth type to SME Roam profile
5267 in the iw_set_ap_address */
5268 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5269 pHddStaCtx->conn_info.authType =
5270 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5271
5272 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5273 pHddStaCtx->conn_info.authType =
5274 eCSR_AUTH_TYPE_SHARED_KEY;
5275
5276 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5277 /*Not supported */
5278 pHddStaCtx->conn_info.authType =
5279 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5280 pWextState->roamProfile.AuthType.authType[0] =
5281 pHddStaCtx->conn_info.authType;
5282 }
5283 break;
5284
5285 case IW_AUTH_KEY_MGMT:
5286 {
5287#ifdef FEATURE_WLAN_ESE
5288#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5289 /*Check for CCKM AKM type */
5290 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5291 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5292 /* Set the CCKM bit in authKeyMgmt */
5293 /*
5294 * Right now, this breaks all ref to authKeyMgmt because
5295 * our code doesn't realize it is a "bitfield"
5296 */
5297 pWextState->authKeyMgmt |=
5298 IW_AUTH_KEY_MGMT_CCKM;
5299 /* Set the key management to 802.1X */
5300 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5301 pWextState->isESEConnection = true;
5302 /*
5303 * This is test code. I need to actually KNOW whether
5304 * this is an RSN Assoc or WPA.
5305 */
5306 pWextState->collectedAuthType =
5307 eCSR_AUTH_TYPE_CCKM_RSN;
5308 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5309 /* Save the key management */
5310 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5311 pWextState->collectedAuthType =
5312 eCSR_AUTH_TYPE_RSN;
5313 } else
5314 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5315 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5316 /* Save the key management anyway */
5317 pWextState->authKeyMgmt = wrqu->param.value;
5318 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5319 /* Save the key management */
5320 pWextState->authKeyMgmt |=
5321 IW_AUTH_KEY_MGMT_802_1X;
5322 pWextState->collectedAuthType =
5323 eCSR_AUTH_TYPE_RSN;
5324 }
5325#else
5326 /* Save the key management */
5327 pWextState->authKeyMgmt = wrqu->param.value;
5328#endif /* FEATURE_WLAN_ESE */
5329 }
5330 break;
5331
5332 case IW_AUTH_TKIP_COUNTERMEASURES:
5333 {
5334 if (wrqu->param.value) {
5335 hddLog(LOG2,
5336 "Counter Measure started %d",
5337 wrqu->param.value);
5338 pWextState->mTKIPCounterMeasures =
5339 TKIP_COUNTER_MEASURE_STARTED;
5340 } else {
5341 hddLog(LOG2,
5342 "Counter Measure stopped=%d",
5343 wrqu->param.value);
5344 pWextState->mTKIPCounterMeasures =
5345 TKIP_COUNTER_MEASURE_STOPED;
5346 }
5347 }
5348 break;
5349 case IW_AUTH_DROP_UNENCRYPTED:
5350 case IW_AUTH_WPA_ENABLED:
5351 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5352 case IW_AUTH_ROAMING_CONTROL:
5353 case IW_AUTH_PRIVACY_INVOKED:
5354
5355 default:
5356
5357 hddLog(LOGW, FL("called with unsupported auth type %d"),
5358 wrqu->param.flags & IW_AUTH_INDEX);
5359 break;
5360 }
5361
5362 EXIT();
5363 return 0;
5364}
5365
5366/**
5367 * iw_set_auth() - set auth callback function
5368 * @dev: Pointer to the net device.
5369 * @info: Pointer to the iw_request_info.
5370 * @wrqu: Pointer to the iwreq_data.
5371 * @extra: Pointer to the data.
5372 *
5373 * Return: 0 for success, error number on failure.
5374 */
5375int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5376 union iwreq_data *wrqu, char *extra)
5377{
5378 int ret;
5379
5380 cds_ssr_protect(__func__);
5381 ret = __iw_set_auth(dev, info, wrqu, extra);
5382 cds_ssr_unprotect(__func__);
5383
5384 return ret;
5385}
5386
5387/**
5388 * __iw_get_auth() -
5389 * This function returns the auth type to the wpa_supplicant
5390 * @dev: pointer to the net device
5391 * @info: pointer to the iw request info
5392 * @wrqu: pointer to iwreq_data
5393 * @extra: pointer to the data
5394 *
5395 * Return: 0 on success, error number otherwise
5396 */
5397static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5398 union iwreq_data *wrqu, char *extra)
5399{
5400 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5401 hdd_context_t *hdd_ctx;
5402 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5403 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5404 int ret;
5405
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005406 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005407
5408 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5409 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305410 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005411 return ret;
5412
5413 switch (pRoamProfile->negotiatedAuthType) {
5414 case eCSR_AUTH_TYPE_WPA_NONE:
5415 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5416 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5417 break;
5418 case eCSR_AUTH_TYPE_WPA:
5419 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5420 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5421 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005422
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005423 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005424 case eCSR_AUTH_TYPE_RSN:
5425 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5426 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5427 break;
5428 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5429 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5430 break;
5431 case eCSR_AUTH_TYPE_SHARED_KEY:
5432 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5433 break;
5434 case eCSR_AUTH_TYPE_UNKNOWN:
5435 hddLog(LOG1, FL("called with unknown auth type"));
5436 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5437 break;
5438 case eCSR_AUTH_TYPE_AUTOSWITCH:
5439 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5440 break;
5441 case eCSR_AUTH_TYPE_WPA_PSK:
5442 hddLog(LOG1, FL("called with WPA PSK auth type"));
5443 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5444 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005445
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005446 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005447 case eCSR_AUTH_TYPE_RSN_PSK:
5448#ifdef WLAN_FEATURE_11W
5449 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5450 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5451#endif
5452 hddLog(LOG1, FL("called with RSN PSK auth type"));
5453 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5454 return -EIO;
5455 default:
5456 hddLog(LOGE, FL("called with unknown auth type"));
5457 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5458 return -EIO;
5459 }
5460 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5461 switch (pRoamProfile->negotiatedUCEncryptionType) {
5462 case eCSR_ENCRYPT_TYPE_NONE:
5463 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5464 break;
5465 case eCSR_ENCRYPT_TYPE_WEP40:
5466 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5467 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5468 break;
5469 case eCSR_ENCRYPT_TYPE_TKIP:
5470 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5471 break;
5472 case eCSR_ENCRYPT_TYPE_WEP104:
5473 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5474 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5475 break;
5476 case eCSR_ENCRYPT_TYPE_AES:
5477 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5478 break;
5479 default:
5480 hddLog(LOG1, FL("called with unknown auth type %d"),
5481 pRoamProfile->negotiatedUCEncryptionType);
5482 return -EIO;
5483 }
5484 }
5485
5486 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5487 switch (pRoamProfile->negotiatedMCEncryptionType) {
5488 case eCSR_ENCRYPT_TYPE_NONE:
5489 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5490 break;
5491 case eCSR_ENCRYPT_TYPE_WEP40:
5492 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5493 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5494 break;
5495 case eCSR_ENCRYPT_TYPE_TKIP:
5496 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5497 break;
5498 case eCSR_ENCRYPT_TYPE_WEP104:
5499 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5500 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5501 break;
5502 case eCSR_ENCRYPT_TYPE_AES:
5503 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5504 break;
5505 default:
5506 hddLog(LOG1, FL("called with unknown auth type %d"),
5507 pRoamProfile->negotiatedMCEncryptionType);
5508 return -EIO;
5509 }
5510 }
5511
5512 hddLog(LOG1, FL("called with auth type %d"),
5513 pRoamProfile->AuthType.authType[0]);
5514 EXIT();
5515 return 0;
5516}
5517
5518/**
5519 * iw_get_auth() - get auth callback function
5520 * @dev: Pointer to the net device.
5521 * @info: Pointer to the iw_request_info.
5522 * @wrqu: Pointer to the iwreq_data.
5523 * @extra: Pointer to the data.
5524 *
5525 * Return: 0 for success, error number on failure.
5526 */
5527int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5528 union iwreq_data *wrqu, char *extra)
5529{
5530 int ret;
5531
5532 cds_ssr_protect(__func__);
5533 ret = __iw_get_auth(dev, info, wrqu, extra);
5534 cds_ssr_unprotect(__func__);
5535
5536 return ret;
5537}
5538
5539/**
5540 * __iw_set_ap_address() - set ap address
5541 * @dev: pointer to the net device
5542 * @info: pointer to the iw request info
5543 * @wrqu: pointer to iwreq_data
5544 * @extra: pointer to the data
5545 *
5546 * This function updates the HDD global station context connection info
5547 * BSSID with the MAC address received from the wpa_supplicant.
5548 *
5549 * Return: 0 on success, error number otherwise
5550 */
5551static int __iw_set_ap_address(struct net_device *dev,
5552 struct iw_request_info *info,
5553 union iwreq_data *wrqu, char *extra)
5554{
5555
5556 hdd_adapter_t *adapter;
5557 hdd_context_t *hdd_ctx;
5558 hdd_station_ctx_t *pHddStaCtx =
5559 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5560 uint8_t *pMacAddress = NULL;
5561 int ret;
5562
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005563 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005564
5565 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5566
5567 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5568 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305569 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005570 return ret;
5571
5572 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5573 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305574 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305575 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005576 EXIT();
5577
5578 return 0;
5579}
5580
5581/**
5582 * iw_set_ap_address() - set ap addresses callback function
5583 * @dev: Pointer to the net device.
5584 * @info: Pointer to the iw_request_info.
5585 * @wrqu: Pointer to the iwreq_data.
5586 * @extra: Pointer to the data.
5587 *
5588 * Return: 0 for success, error number on failure.
5589 */
5590int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5591 union iwreq_data *wrqu, char *extra)
5592{
5593 int ret;
5594
5595 cds_ssr_protect(__func__);
5596 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5597 cds_ssr_unprotect(__func__);
5598
5599 return ret;
5600}
5601
5602/**
5603 * __iw_get_ap_address() - get ap address
5604 * @dev: pointer to the net device
5605 * @info: pointer to the iw request info
5606 * @wrqu: pointer to iwreq_data
5607 * @extra: pointer to the data
5608 *
5609 * This function returns currently associated BSSID.
5610 *
5611 * Return: 0 on success, error number otherwise
5612 */
5613static int __iw_get_ap_address(struct net_device *dev,
5614 struct iw_request_info *info,
5615 union iwreq_data *wrqu, char *extra)
5616{
5617 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5618 hdd_context_t *hdd_ctx;
5619 hdd_station_ctx_t *pHddStaCtx =
5620 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5621 int ret;
5622
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005623 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005624
5625 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5626 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305627 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005628 return ret;
5629
5630 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5631 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305632 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005633 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305634 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005635 } else {
5636 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5637 }
5638 EXIT();
5639 return 0;
5640}
5641
5642/**
5643 * iw_get_ap_address() - get ap addresses callback function
5644 * @dev: Pointer to the net device.
5645 * @info: Pointer to the iw_request_info.
5646 * @wrqu: Pointer to the iwreq_data.
5647 * @extra: Pointer to the data.
5648 *
5649 * Return: 0 for success, error number on failure.
5650 */
5651int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5652 union iwreq_data *wrqu, char *extra)
5653{
5654 int ret;
5655
5656 cds_ssr_protect(__func__);
5657 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5658 cds_ssr_unprotect(__func__);
5659
5660 return ret;
5661}