blob: 2c09426a1b488a6be23df65bec5af5914463be84 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
3 *
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"
58
59/* These are needed to recognize WPA and RSN suite types */
60#define HDD_WPA_OUI_SIZE 4
61#define HDD_RSN_OUI_SIZE 4
62uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
63uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
64uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
65uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
66uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
67uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
68
69#ifdef FEATURE_WLAN_ESE
70/* CCKM */
71uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
72/* CCKM */
73uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
74#endif /* FEATURE_WLAN_ESE */
75
76/* group cipher */
77uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
78
79/* WEP-40 or RSN */
80uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
81
82/* TKIP or RSN-PSK */
83uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
84
85/* Reserved */
86uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
87
88/* AES-CCMP */
89uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
90
91/* WEP-104 */
92uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
93
94#ifdef WLAN_FEATURE_11W
95/* RSN-PSK-SHA256 */
96uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
97
98/* RSN-8021X-SHA256 */
99uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
100#endif
101
102#if defined(WLAN_FEATURE_VOWIFI_11R)
103/* Offset where the EID-Len-IE, start. */
104#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
105#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
106#endif
107
108#define BEACON_FRAME_IES_OFFSET 12
109#define HDD_PEER_AUTHORIZE_WAIT 10
110
111/**
112 * hdd_conn_set_authenticated() - set authentication state
113 * @pAdapter: pointer to the adapter
114 * @authState: authentication state
115 *
116 * This function updates the global HDD station context
117 * authentication state.
118 *
119 * Return: none
120 */
121static void
122hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
123{
124 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
125 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
126
127 /* save the new connection state */
128 hddLog(LOG1,
129 FL("Authenticated state Changed from oldState:%d to State:%d"),
130 pHddStaCtx->conn_info.uIsAuthenticated, authState);
131 pHddStaCtx->conn_info.uIsAuthenticated = authState;
132
133 /* Check is pending ROC request or not when auth state changed */
134 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
135}
136
137/**
138 * hdd_conn_set_connection_state() - set connection state
139 * @pAdapter: pointer to the adapter
140 * @connState: connection state
141 *
142 * This function updates the global HDD station context connection state.
143 *
144 * Return: none
145 */
146void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
147 eConnectionState connState)
148{
149 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
150 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
151
152 /* save the new connection state */
153 hddLog(LOG1, FL("ConnectionState Changed from oldState:%d to State:%d"),
154 pHddStaCtx->conn_info.connState, connState);
155 pHddStaCtx->conn_info.connState = connState;
156
157 /* Check is pending ROC request or not when connection state changed */
158 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
159}
160
161/**
162 * hdd_conn_get_connection_state() - get connection state
163 * @pAdapter: pointer to the adapter
164 * @pConnState: pointer to connection state
165 *
166 * This function updates the global HDD station context connection state.
167 *
168 * Return: true if (Infra Associated or IBSS Connected)
169 * and sets output parameter pConnState;
170 * false otherwise
171 */
172static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
173 eConnectionState *pConnState)
174{
175 bool fConnected = false;
176 eConnectionState connState;
177
178 /* get the connection state. */
179 connState = pHddStaCtx->conn_info.connState;
180
181 if (eConnectionState_Associated == connState ||
182 eConnectionState_IbssConnected == connState ||
183 eConnectionState_IbssDisconnected == connState) {
184 fConnected = true;
185 }
186
187 if (pConnState)
188 *pConnState = connState;
189
190 return fConnected;
191}
192
193/**
194 * hdd_is_connecting() - Function to check connection progress
195 * @hdd_sta_ctx: pointer to global HDD Station context
196 *
197 * Return: true if connecting, false otherwise
198 */
199bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
200{
201 return hdd_sta_ctx->conn_info.connState ==
202 eConnectionState_Connecting;
203}
204
205/**
206 * hdd_conn_is_connected() - Function to check connection status
207 * @pHddStaCtx: pointer to global HDD Station context
208 *
209 * Return: false if any errors encountered, true otherwise
210 */
211bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
212{
213 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
214}
215
216/**
217 * hdd_conn_get_connected_band() - get current connection radio band
218 * @pHddStaCtx: pointer to global HDD Station context
219 *
220 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
221 * eCSR_BAND_ALL if not connected
222 */
223eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
224{
225 uint8_t staChannel = 0;
226
227 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
228 staChannel = pHddStaCtx->conn_info.operationChannel;
229
230 if (staChannel > 0 && staChannel < 14)
231 return eCSR_BAND_24;
232 else if (staChannel >= 36 && staChannel <= 184)
233 return eCSR_BAND_5G;
234 else /* If station is not connected return as eCSR_BAND_ALL */
235 return eCSR_BAND_ALL;
236}
237
238/**
239 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
240 * @pHddStaCtx: pointer to global HDD Station context
241 * @pConnectedCipherAlgo: pointer to connected cipher algo
242 *
243 * Return: false if any errors encountered, true otherwise
244 */
245static inline bool
246hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
247 eCsrEncryptionType *pConnectedCipherAlgo)
248{
249 bool fConnected = false;
250
251 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
252
253 if (pConnectedCipherAlgo)
254 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
255
256 return fConnected;
257}
258
259/**
260 * hdd_conn_get_connected_bss_type() - get current bss type
261 * @pHddStaCtx: pointer to global HDD Station context
262 * @pConnectedBssType: pointer to connected bss type
263 *
264 * Return: false if any errors encountered, true otherwise
265 */
266inline bool
267hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
268 eMib_dot11DesiredBssType *pConnectedBssType)
269{
270 bool fConnected = false;
271
272 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
273
274 if (pConnectedBssType) {
275 *pConnectedBssType =
276 pHddStaCtx->conn_info.connDot11DesiredBssType;
277 }
278
279 return fConnected;
280}
281
282/**
283 * hdd_conn_save_connected_bss_type() - set connected bss type
284 * @pHddStaCtx: pointer to global HDD Station context
285 * @csr_roamBssType: bss type
286 *
287 * Return: none
288 */
289static inline void
290hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
291 eCsrRoamBssType csr_roamBssType)
292{
293 switch (csr_roamBssType) {
294 case eCSR_BSS_TYPE_INFRASTRUCTURE:
295 pHddStaCtx->conn_info.connDot11DesiredBssType =
296 eMib_dot11DesiredBssType_infrastructure;
297 break;
298
299 case eCSR_BSS_TYPE_IBSS:
300 case eCSR_BSS_TYPE_START_IBSS:
301 pHddStaCtx->conn_info.connDot11DesiredBssType =
302 eMib_dot11DesiredBssType_independent;
303 break;
304
305 /** We will never set the BssType to 'any' when attempting a connection
306 so CSR should never send this back to us.*/
307 case eCSR_BSS_TYPE_ANY:
308 default:
309 CDF_ASSERT(0);
310 break;
311 }
312}
313
314/**
315 * hdd_conn_save_connect_info() - save current connection information
316 * @pAdapter: pointer to adapter
317 * @pRoamInfo: pointer to roam info
318 * @eBssType: bss type
319 *
320 * Return: none
321 */
322static void
323hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
324 eCsrRoamBssType eBssType)
325{
326 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
327 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
328
329 CDF_ASSERT(pRoamInfo);
330
331 if (pRoamInfo) {
332 /* Save the BSSID for the connection */
333 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
334 CDF_ASSERT(pRoamInfo->pBssDesc);
335 cdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
336 &pRoamInfo->bssid);
337
338 /*
339 * Save the Station ID for this station from
340 * the 'Roam Info'. For IBSS mode, staId is
341 * assigned in NEW_PEER_IND. For reassoc,
342 * the staID doesn't change and it may be invalid
343 * in this structure so no change here.
344 */
345 if (!pRoamInfo->fReassocReq) {
346 pHddStaCtx->conn_info.staId[0] =
347 pRoamInfo->staId;
348 }
349 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
350 cdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
351 &pRoamInfo->bssid);
352 } else {
353 /*
354 * can't happen. We need a valid IBSS or Infra setting
355 * in the BSSDescription or we can't function.
356 */
357 CDF_ASSERT(0);
358 }
359
360 /* notify WMM */
361 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
362
363 if (!pRoamInfo->u.pConnectedProfile) {
364 CDF_ASSERT(pRoamInfo->u.pConnectedProfile);
365 } else {
366 /* Get Multicast Encryption Type */
367 encryptType =
368 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
369 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
370 /* Get Unicast Encryption Type */
371 encryptType =
372 pRoamInfo->u.pConnectedProfile->EncryptionType;
373 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
374
375 pHddStaCtx->conn_info.authType =
376 pRoamInfo->u.pConnectedProfile->AuthType;
377
378 pHddStaCtx->conn_info.operationChannel =
379 pRoamInfo->u.pConnectedProfile->operationChannel;
380
381 /* Save the ssid for the connection */
382 cdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
383 &pRoamInfo->u.pConnectedProfile->SSID,
384 sizeof(tSirMacSSid));
385
386 /* Save dot11mode in which STA associated to AP */
387 pHddStaCtx->conn_info.dot11Mode =
388 pRoamInfo->u.pConnectedProfile->dot11Mode;
389
390 pHddStaCtx->conn_info.proxyARPService =
391 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530392
393 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
394
395 pHddStaCtx->conn_info.rate_flags =
396 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800397 }
398 }
399 /* save the connected BssType */
400 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
401}
402
403#if defined(WLAN_FEATURE_VOWIFI_11R)
404/**
405 * hdd_send_ft_assoc_response() - send fast transition assoc response
406 * @dev: pointer to net device
407 * @pAdapter: pointer to adapter
408 * @pCsrRoamInfo: pointer to roam info
409 *
410 * Send the 11R key information to the supplicant. Only then can the supplicant
411 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
412 * for the same purpose.)
413 *
414 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
415 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
416 * This is the Assoc Response.
417 *
418 * Return: none
419 */
420static void
421hdd_send_ft_assoc_response(struct net_device *dev,
422 hdd_adapter_t *pAdapter,
423 tCsrRoamInfo *pCsrRoamInfo)
424{
425 union iwreq_data wrqu;
426 char *buff;
427 unsigned int len = 0;
428 u8 *pFTAssocRsp = NULL;
429
430 if (pCsrRoamInfo->nAssocRspLength == 0) {
431 hddLog(LOGE,
432 FL("pCsrRoamInfo->nAssocRspLength=%d"),
433 (int)pCsrRoamInfo->nAssocRspLength);
434 return;
435 }
436
437 pFTAssocRsp =
438 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
439 pCsrRoamInfo->nAssocReqLength);
440 if (pFTAssocRsp == NULL) {
441 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
442 return;
443 }
444 /* pFTAssocRsp needs to point to the IEs */
445 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
446 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
447 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
448
449 /* We need to send the IEs to the supplicant. */
450 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
451 if (buff == NULL) {
452 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
453 return;
454 }
455 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
456 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
457 wrqu.data.length = len;
458 memset(buff, 0, IW_GENERIC_IE_MAX);
459 memcpy(buff, pFTAssocRsp, len);
460 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
461
462 kfree(buff);
463}
464#endif /* WLAN_FEATURE_VOWIFI_11R */
465
466#ifdef WLAN_FEATURE_VOWIFI_11R
467/**
468 * hdd_send_ft_event() - send fast transition event
469 * @pAdapter: pointer to adapter
470 *
471 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
472 * FT events to the supplicant. At the reception of Auth2 we send the RIC
473 * followed by the auth response IEs to the supplicant.
474 * Once both are received in the supplicant, an FT event is generated
475 * to the supplicant.
476 *
477 * Return: none
478 */
479static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
480{
481 uint16_t auth_resp_len = 0;
482 uint32_t ric_ies_length = 0;
483 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
484
485#if defined(KERNEL_SUPPORT_11R_CFG80211)
486 struct cfg80211_ft_event_params ftEvent;
487 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
488 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
489 struct net_device *dev = pAdapter->dev;
490#else
491 char *buff;
492 union iwreq_data wrqu;
493 uint16_t str_len;
494#endif
495
496#if defined(KERNEL_SUPPORT_11R_CFG80211)
497 cdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
498 cdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
499
500 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
501 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
502 if (ric_ies_length == 0) {
503 hddLog(LOGW,
504 FL("RIC IEs is of length 0 not sending RIC Information for now"));
505 }
506
507 ftEvent.ric_ies = ricIe;
508 ftEvent.ric_ies_len = ric_ies_length;
509 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
510
511 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
512 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
513 &auth_resp_len);
514
515 if (auth_resp_len == 0) {
516 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
517 return;
518 }
519
520 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
521
522 ftEvent.target_ap = ftIe;
523
524 ftEvent.ies = (u8 *) (ftIe + CDF_MAC_ADDR_SIZE);
525 ftEvent.ies_len = auth_resp_len - CDF_MAC_ADDR_SIZE;
526
527 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
528 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
529 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
530 ftEvent.target_ap[0], ftEvent.target_ap[1],
531 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
532 ftEvent.target_ap[5]);
533
534 (void)cfg80211_ft_event(dev, &ftEvent);
535
536#else
537 /* We need to send the IEs to the supplicant */
538 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
539 if (buff == NULL) {
540 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
541 return;
542 }
543 cdf_mem_zero(buff, IW_CUSTOM_MAX);
544
545 /* Sme needs to send the RIC IEs first */
546 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
547 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
548 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
549 &ric_ies_length);
550 if (ric_ies_length == 0) {
551 hddLog(LOGW,
552 FL("RIC IEs is of length 0 not sending RIC Information for now"));
553 } else {
554 wrqu.data.length = str_len + ric_ies_length;
555 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
556 }
557
558 /* Sme needs to provide the Auth Resp */
559 cdf_mem_zero(buff, IW_CUSTOM_MAX);
560 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
561 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
562 (u8 *) &buff[str_len],
563 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
564
565 if (auth_resp_len == 0) {
566 kfree(buff);
567 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
568 return;
569 }
570
571 wrqu.data.length = str_len + auth_resp_len;
572 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
573
574 kfree(buff);
575#endif
576}
577
578#endif /* WLAN_FEATURE_VOWIFI_11R */
579
580#ifdef FEATURE_WLAN_ESE
581/**
582 * hdd_send_new_ap_channel_info() - send new ap channel info
583 * @dev: pointer to net device
584 * @pAdapter: pointer to adapter
585 * @pCsrRoamInfo: pointer to roam info
586 *
587 * Send the ESE required "new AP Channel info" to the supplicant.
588 * (This keeps the supplicant "up to date" on the current channel.)
589 *
590 * The current (new AP) channel information is passed in.
591 *
592 * Return: none
593 */
594static void
595hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
596 tCsrRoamInfo *pCsrRoamInfo)
597{
598 union iwreq_data wrqu;
599 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
600
601 if (descriptor == NULL) {
602 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
603 return;
604 }
605 /*
606 * Send the Channel event, the supplicant needs this to generate
607 * the Adjacent AP report.
608 */
609 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
610 descriptor->channelId);
611 memset(&wrqu, '\0', sizeof(wrqu));
612 wrqu.freq.m = descriptor->channelId;
613 wrqu.freq.e = 0;
614 wrqu.freq.i = 0;
615 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
616}
617
618#endif /* FEATURE_WLAN_ESE */
619
620/**
621 * hdd_send_update_beacon_ies_event() - send update beacons ie event
622 * @pAdapter: pointer to adapter
623 * @pCsrRoamInfo: pointer to roam info
624 *
625 * Return: none
626 */
627static void
628hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
629 tCsrRoamInfo *pCsrRoamInfo)
630{
631 union iwreq_data wrqu;
632 u8 *pBeaconIes;
633 u8 currentLen = 0;
634 char *buff;
635 int totalIeLen = 0, currentOffset = 0, strLen;
636
637 memset(&wrqu, '\0', sizeof(wrqu));
638
639 if (0 == pCsrRoamInfo->nBeaconLength) {
640 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
641 return;
642 }
643 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
644 if (pBeaconIes == NULL) {
645 hddLog(LOGW, FL("Beacon IEs is NULL"));
646 return;
647 }
648 /* pBeaconIes needs to point to the IEs */
649 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
650 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
651 hddLog(LOG1, FL("Beacon IEs length = %d"),
652 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
653
654 /* We need to send the IEs to the supplicant. */
655 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
656 if (buff == NULL) {
657 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
658 return;
659 }
660 cdf_mem_zero(buff, IW_CUSTOM_MAX);
661
662 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
663 currentLen = strLen + 1;
664
665 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
666 do {
667 /*
668 * If the beacon size exceeds max CUSTOM event size, break it
669 * into chunks of CUSTOM event max size and send it to
670 * supplicant. Changes are done in supplicant to handle this.
671 */
672 cdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
673 currentLen =
674 CDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
675 cdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
676 currentLen);
677 currentOffset += currentLen;
678 totalIeLen -= currentLen;
679 wrqu.data.length = strLen + 1 + currentLen;
680 if (totalIeLen)
681 buff[strLen] = 1; /* more chunks pending */
682 else
683 buff[strLen] = 0; /* last chunk */
684
685 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
686 currentLen);
687 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
688 } while (totalIeLen > 0);
689
690 kfree(buff);
691}
692
693/**
694 * hdd_send_association_event() - send association event
695 * @dev: pointer to net device
696 * @pCsrRoamInfo: pointer to roam info
697 *
698 * Return: none
699 */
700static void hdd_send_association_event(struct net_device *dev,
701 tCsrRoamInfo *pCsrRoamInfo)
702{
703 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
704 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
705 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
706 union iwreq_data wrqu;
707 int we_event;
708 char *msg;
709 struct cdf_mac_addr peerMacAddr;
710
711#ifdef WLAN_FEATURE_VOWIFI_11R
712 /* Added to find the auth type on the fly at run time */
713 /* rather than with cfg to see if FT is enabled */
714 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
715 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
716#endif
717
718 memset(&wrqu, '\0', sizeof(wrqu));
719 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
720 we_event = SIOCGIWAP;
721#ifdef WLAN_FEATURE_ROAM_OFFLOAD
722 if (NULL != pCsrRoamInfo)
723 if (pCsrRoamInfo->roamSynchInProgress)
724 /* change logging before release */
725 hddLog(LOG4, "LFR3:hdd_send_association_event");
726#endif
727 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
728 if (!pCsrRoamInfo) {
729 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
730 return;
731 }
732
733 cds_incr_active_session(pHddCtx, pAdapter->device_mode,
734 pAdapter->sessionId);
735 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
736 sizeof(pCsrRoamInfo->pBssDesc->bssId));
737
738#ifdef WLAN_FEATURE_P2P_DEBUG
739 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
740 if (global_p2p_connection_status ==
741 P2P_CLIENT_CONNECTING_STATE_1) {
742 global_p2p_connection_status =
743 P2P_CLIENT_CONNECTED_STATE_1;
744 hddLog(LOGE,
745 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
746 } else if (global_p2p_connection_status ==
747 P2P_CLIENT_CONNECTING_STATE_2) {
748 global_p2p_connection_status =
749 P2P_CLIENT_COMPLETED_STATE;
750 hddLog(LOGE,
751 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
752 }
753 }
754#endif
755 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
756 MAC_ADDRESS_STR "\n",
757 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
758 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
759 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
760
761 /*
762 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
763 * is Enabled Or Send IWEVASSOCRESPIE Event if
764 * WLAN_FEATURE_VOWIFI_11R is Enabled and fFTEnable is true.
765 */
766#ifdef WLAN_FEATURE_VOWIFI_11R
767 /* Send FT Keys to the supplicant when FT is enabled */
768 if ((pRoamProfile->AuthType.authType[0] ==
769 eCSR_AUTH_TYPE_FT_RSN_PSK)
770 || (pRoamProfile->AuthType.authType[0] ==
771 eCSR_AUTH_TYPE_FT_RSN)
772#ifdef FEATURE_WLAN_ESE
773 || (pRoamProfile->AuthType.authType[0] ==
774 eCSR_AUTH_TYPE_CCKM_RSN)
775 || (pRoamProfile->AuthType.authType[0] ==
776 eCSR_AUTH_TYPE_CCKM_WPA)
777#endif
778 ) {
779 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
780 }
781#endif
782 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
783 tSirSmeChanInfo chan_info;
784 cdf_copy_macaddr(&peerMacAddr,
785 &pHddStaCtx->conn_info.bssId);
786 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
787 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
788 chan_info.info = pCsrRoamInfo->chan_info.info;
789 chan_info.band_center_freq1 =
790 pCsrRoamInfo->chan_info.band_center_freq1;
791 chan_info.band_center_freq2 =
792 pCsrRoamInfo->chan_info.band_center_freq2;
793 chan_info.reg_info_1 =
794 pCsrRoamInfo->chan_info.reg_info_1;
795 chan_info.reg_info_2 =
796 pCsrRoamInfo->chan_info.reg_info_2;
797
798 /* send peer status indication to oem app */
799 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
800 ePeerConnected,
801 pCsrRoamInfo->
802 timingMeasCap,
803 pAdapter->sessionId,
804 &chan_info);
805 }
806#ifdef MSM_PLATFORM
807#ifdef CONFIG_CNSS
808 /* start timer in sta/p2p_cli */
809 spin_lock_bh(&pHddCtx->bus_bw_lock);
810 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
811 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
812 spin_unlock_bh(&pHddCtx->bus_bw_lock);
813 hdd_start_bus_bw_compute_timer(pAdapter);
814#endif
815#endif
816 } else if (eConnectionState_IbssConnected == /* IBss Associated */
817 pHddStaCtx->conn_info.connState) {
Krunal Soni2c68f232015-10-26 20:52:51 -0700818 cds_update_connection_info(pHddCtx,
819 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
821 ETH_ALEN);
822 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
823 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
824 } else { /* Not Associated */
825
826 pr_info("wlan: disconnected\n");
827 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
828 cds_decr_session_set_pcl(
829 pHddCtx, pAdapter->device_mode,
830 pAdapter->sessionId);
831#if defined(FEATURE_WLAN_LFR)
832 wlan_hdd_enable_roaming(pAdapter);
833#endif
834
835#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
836 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
837#endif
838
839 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
840 cdf_copy_macaddr(&peerMacAddr,
841 &pHddStaCtx->conn_info.bssId);
842
843 /* send peer status indication to oem app */
844 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
845 ePeerDisconnected, 0,
846 pAdapter->sessionId,
847 NULL);
848 }
849#ifdef WLAN_FEATURE_LPSS
850 pAdapter->rssi_send = false;
851 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
852#endif
853#ifdef FEATURE_WLAN_TDLS
854 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) &&
855 (pCsrRoamInfo)) {
856 hddLog(LOG4,
857 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
858 pCsrRoamInfo->tdls_prohibited,
859 pCsrRoamInfo->tdls_chan_swit_prohibited);
860
861 wlan_hdd_update_tdls_info(pAdapter,
862 pCsrRoamInfo->tdls_prohibited,
863 pCsrRoamInfo->tdls_chan_swit_prohibited);
864 }
865#endif
866#ifdef MSM_PLATFORM
867 /* stop timer in sta/p2p_cli */
868 spin_lock_bh(&pHddCtx->bus_bw_lock);
869 pAdapter->prev_tx_packets = 0;
870 pAdapter->prev_rx_packets = 0;
871 spin_unlock_bh(&pHddCtx->bus_bw_lock);
872 hdd_stop_bus_bw_compute_timer(pAdapter);
873#endif
874 }
875 cds_dump_concurrency_info(pHddCtx);
876 /* Send SCC/MCC Switching event to IPA */
877 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
878
879 msg = NULL;
880 /*During the WLAN uninitialization,supplicant is stopped before the
881 driver so not sending the status of the connection to supplicant */
882 if ((pHddCtx->isLoadInProgress != true) &&
883 (pHddCtx->isUnloadInProgress != true)) {
884 wireless_send_event(dev, we_event, &wrqu, msg);
885#ifdef FEATURE_WLAN_ESE
886 if (eConnectionState_Associated ==
887 pHddStaCtx->conn_info.connState) {
888 if ((pRoamProfile->AuthType.authType[0] ==
889 eCSR_AUTH_TYPE_CCKM_RSN) ||
890 (pRoamProfile->AuthType.authType[0] ==
891 eCSR_AUTH_TYPE_CCKM_WPA))
892 hdd_send_new_ap_channel_info(dev, pAdapter,
893 pCsrRoamInfo);
894 }
895#endif
896 }
897}
898
899/**
900 * hdd_conn_remove_connect_info() - remove connection info
901 * @pHddStaCtx: pointer to global HDD station context
902 * @pCsrRoamInfo: pointer to roam info
903 *
904 * Return: none
905 */
906static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
907{
908 /* Remove staId, bssId and peerMacAddress */
909 pHddStaCtx->conn_info.staId[0] = 0;
910 cdf_mem_zero(&pHddStaCtx->conn_info.bssId, CDF_MAC_ADDR_SIZE);
911 cdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
912 CDF_MAC_ADDR_SIZE);
913
914 /* Clear all security settings */
915 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
916 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
917 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
918
919 cdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
920 cdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
921
922 /* Set not-connected state */
923 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
924 pHddStaCtx->conn_info.proxyARPService = 0;
925
926 cdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
927}
928
929/**
930 * hdd_roam_deregister_sta() - deregister station
931 * @pAdapter: pointer to adapter
932 * @staId: station identifier
933 *
934 * Return: CDF_STATUS enumeration
935 */
936static CDF_STATUS
937hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
938{
939 CDF_STATUS cdf_status;
940 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
941
942 if (eConnectionState_IbssDisconnected ==
943 pHddStaCtx->conn_info.connState) {
944 /*
945 * Do not set the carrier off when the last peer leaves.
946 * We will set the carrier off while stopping the IBSS.
947 */
948 }
949
950 cdf_status = ol_txrx_clear_peer(staId);
951 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
952 hddLog(LOGE,
953 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
954 staId, cdf_status, cdf_status);
955 }
956 return cdf_status;
957}
958
959/**
960 * hdd_dis_connect_handler() - disconnect event handler
961 * @pAdapter: pointer to adapter
962 * @pRoamInfo: pointer to roam info
963 * @roamId: roam identifier
964 * @roamStatus: roam status
965 * @roamResult: roam result
966 *
967 * This function handles disconnect event:
968 * 1. Disable transmit queues;
969 * 2. Clean up internal connection states and data structures;
970 * 3. Send disconnect indication to supplicant.
971 *
972 * Return: CDF_STATUS enumeration
973 */
974static CDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
975 tCsrRoamInfo *pRoamInfo,
976 uint32_t roamId,
977 eRoamCmdStatus roamStatus,
978 eCsrRoamResult roamResult)
979{
980 CDF_STATUS status = CDF_STATUS_SUCCESS;
981 CDF_STATUS vstatus;
982 struct net_device *dev = pAdapter->dev;
983 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
984 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
985 uint8_t sta_id;
986 bool sendDisconInd = true;
987
988 if (dev == NULL) {
989 hddLog(LOGE, FL("net_dev is released return"));
990 return CDF_STATUS_E_FAILURE;
991 }
992 /* notify apps that we can't pass traffic anymore */
993 hddLog(LOG1, FL("Disabling queues"));
994 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
995 WLAN_CONTROL_PATH);
996
997 if (hdd_ipa_is_enabled(pHddCtx))
998 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
999 WLAN_STA_DISCONNECT,
1000 pHddStaCtx->conn_info.bssId.bytes);
1001
1002#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1003 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1004#endif
1005
1006#ifdef QCA_PKT_PROTO_TRACE
1007 /* STA disconnected, update into trace buffer */
1008 if (pHddCtx->config->gEnableDebugLog)
1009 cds_pkt_trace_buf_update("ST:DISASC");
1010#endif /* QCA_PKT_PROTO_TRACE */
1011
1012 /* HDD has initiated disconnect, do not send disconnect indication
1013 * to kernel. Sending disconnected event to kernel for userspace
1014 * initiated disconnect will be handled by hdd_DisConnectHandler call
1015 * to cfg80211_disconnected.
1016 */
1017 if ((eConnectionState_Disconnecting ==
1018 pHddStaCtx->conn_info.connState) ||
1019 (eConnectionState_NotConnected ==
1020 pHddStaCtx->conn_info.connState)) {
1021 hddLog(LOG1,
1022 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1023 sendDisconInd = false;
1024 }
1025
1026 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1027 INIT_COMPLETION(pAdapter->disconnect_comp_var);
1028 hddLog(LOG1,
1029 FL("Set HDD connState to eConnectionState_Disconnecting"));
1030 hdd_conn_set_connection_state(pAdapter,
1031 eConnectionState_Disconnecting);
1032 }
1033
1034 hdd_clear_roam_profile_ie(pAdapter);
1035 hdd_wmm_init(pAdapter);
1036
1037 /* indicate 'disconnect' status to wpa_supplicant... */
1038 hdd_send_association_event(dev, pRoamInfo);
1039 /* indicate disconnected event to nl80211 */
1040 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1041 /*
1042 * Only send indication to kernel if not initiated
1043 * by kernel
1044 */
1045 if (sendDisconInd) {
1046 /*
1047 * To avoid wpa_supplicant sending "HANGED" CMD
1048 * to ICS UI.
1049 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001050 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1051 if (pRoamInfo->reasonCode ==
1052 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1053 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054 cfg80211_disconnected(dev, pRoamInfo->
1055 reasonCode, NULL,
1056 0, GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001057 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001058 cfg80211_disconnected(dev,
1059 WLAN_REASON_UNSPECIFIED,
1060 NULL, 0,
1061 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001062 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001063
1064 hdd_info("sent disconnected event to nl80211, rssi: %d",
1065 pAdapter->rssi);
1066 }
1067 /*
1068 * During the WLAN uninitialization,supplicant is stopped
1069 * before the driver so not sending the status of the
1070 * connection to supplicant.
1071 */
1072 if ((pHddCtx->isLoadInProgress != true) &&
1073 (pHddCtx->isUnloadInProgress != true)) {
1074#ifdef WLAN_FEATURE_P2P_DEBUG
1075 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1076 if (global_p2p_connection_status ==
1077 P2P_CLIENT_CONNECTED_STATE_1) {
1078 global_p2p_connection_status =
1079 P2P_CLIENT_DISCONNECTED_STATE;
1080 hddLog(LOGE,
1081 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1082 } else if (global_p2p_connection_status ==
1083 P2P_CLIENT_COMPLETED_STATE) {
1084 global_p2p_connection_status =
1085 P2P_NOT_ACTIVE;
1086 hddLog(LOGE,
1087 "[P2P State] P2P Client is removed and moved to inactive state");
1088 }
1089 }
1090#endif
1091
1092 }
1093 }
1094
1095 hdd_wmm_adapter_clear(pAdapter);
1096#if defined(WLAN_FEATURE_VOWIFI_11R)
1097 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
1098#endif
1099 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301100 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301101 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001102 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
1103 if (!CDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301104 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1105 sta_id, status, status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001106 status = CDF_STATUS_E_FAILURE;
1107 }
1108 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301109 /* Clear all the peer sta register with TL. */
1110 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1111 if (0 == pHddStaCtx->conn_info.staId[i])
1112 continue;
1113 sta_id = pHddStaCtx->conn_info.staId[i];
1114 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1115 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
1116 if (!CDF_IS_STATUS_SUCCESS(vstatus)) {
1117 hddLog(LOGE,
1118 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1119 sta_id, status, status);
1120 status = CDF_STATUS_E_FAILURE;
1121 }
1122 /* set the staid and peer mac as 0, all other
1123 * reset are done in hdd_connRemoveConnectInfo.
1124 */
1125 pHddStaCtx->conn_info.staId[i] = 0;
1126 cdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
1127 sizeof(struct cdf_mac_addr));
1128 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1129 pHddCtx->sta_to_adapter[sta_id] = NULL;
1130 }
1131 } else {
1132 sta_id = pHddStaCtx->conn_info.staId[0];
1133 /* We should clear all sta register with TL,
1134 * for now, only one.
1135 */
1136 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
1137 if (!CDF_IS_STATUS_SUCCESS(vstatus)) {
1138 hddLog(LOGE,
1139 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1140 sta_id, status, status);
1141 status = CDF_STATUS_E_FAILURE;
1142 }
1143 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001144 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001145 /* Clear saved connection information in HDD */
1146 hdd_conn_remove_connect_info(pHddStaCtx);
1147 hddLog(LOG1, FL("Set HDD connState to eConnectionState_NotConnected"));
1148 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1149#ifdef WLAN_FEATURE_GTK_OFFLOAD
1150 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1151 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1152 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1153 sizeof(tSirGtkOffloadParams));
1154 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1155 }
1156#endif
1157
1158#ifdef FEATURE_WLAN_TDLS
1159 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1160 wlan_hdd_tdls_disconnection_callback(pAdapter);
1161#endif
1162
1163 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1164 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1165 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1166 (pAdapter),
1167 pAdapter->sessionId);
1168 }
1169 /* Unblock anyone waiting for disconnect to complete */
1170 complete(&pAdapter->disconnect_comp_var);
1171 return status;
1172}
1173
1174/**
1175 * hdd_set_peer_authorized_event() - set peer_authorized_event
1176 * @vdev_id: vdevid
1177 *
1178 * Return: None
1179 */
1180void hdd_set_peer_authorized_event(uint32_t vdev_id)
1181{
1182 hdd_context_t *hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
1183 hdd_adapter_t *adapter = NULL;
1184
1185 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1186 if (adapter == NULL) {
1187 hddLog(LOGE,
1188 "%s: Invalid vdev_id", __func__);
1189 }
1190 complete(&adapter->sta_authorized_event);
1191}
1192
1193/**
1194 * hdd_change_peer_state() - change peer state
1195 * @pAdapter: HDD adapter
1196 * @sta_state: peer state
1197 * @roam_synch_in_progress: roam synch in progress
1198 *
1199 * Return: CDF status
1200 */
1201CDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
1202 uint8_t sta_id,
1203 enum ol_txrx_peer_state sta_state,
1204 bool roam_synch_in_progress)
1205{
1206 struct ol_txrx_peer_t *peer;
1207 CDF_STATUS err;
1208 struct ol_txrx_pdev_t *pdev = cds_get_context(CDF_MODULE_ID_TXRX);
1209
1210 if (!pdev) {
1211 hdd_err("Failed to get txrx context");
1212 return CDF_STATUS_E_FAULT;
1213 }
1214
1215 if (sta_id >= WLAN_MAX_STA_COUNT) {
1216 hddLog(LOGE, "Invalid sta id :%d", sta_id);
1217 return CDF_STATUS_E_INVAL;
1218 }
1219
1220 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1221 if (!peer)
1222 return CDF_STATUS_E_FAULT;
1223
1224 err = ol_txrx_peer_state_update(pdev,
1225 (u_int8_t *) peer->mac_addr.raw, sta_state);
1226 if (err != CDF_STATUS_SUCCESS) {
1227 hddLog(LOGE, "peer state update failed");
1228 return CDF_STATUS_E_FAULT;
1229 }
1230#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1231 if (roam_synch_in_progress)
1232 return CDF_STATUS_SUCCESS;
1233#endif
1234
1235 if (sta_state == ol_txrx_peer_state_auth) {
1236#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1237 /* make sure event is reset */
1238 INIT_COMPLETION(pAdapter->sta_authorized_event);
1239#endif
1240
1241 err = sme_set_peer_authorized(peer->mac_addr.raw,
1242 hdd_set_peer_authorized_event,
1243 pAdapter->sessionId);
1244 if (err != CDF_STATUS_SUCCESS) {
1245 hddLog(LOGE, "Failed to set the peer state to authorized");
1246 return CDF_STATUS_E_FAULT;
1247 }
1248
1249 if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1250 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1251#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
1252 unsigned long rc;
1253
1254 /* wait for event from firmware to set the event */
1255 rc = wait_for_completion_timeout(
1256 &pAdapter->sta_authorized_event,
1257 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1258 if (!rc) {
1259 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1260 __func__);
1261 }
1262 ol_txrx_vdev_unpause(peer->vdev,
1263 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
1264#endif
1265 }
1266 }
1267 return CDF_STATUS_SUCCESS;
1268}
1269
1270/**
1271 * hdd_roam_register_sta() - register station
1272 * @pAdapter: pointer to adapter
1273 * @pRoamInfo: pointer to roam info
1274 * @staId: station identifier
1275 * @pPeerMacAddress: peer MAC address
1276 * @pBssDesc: pointer to BSS description
1277 *
1278 * Return: CDF_STATUS enumeration
1279 */
1280static CDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
1281 tCsrRoamInfo *pRoamInfo,
1282 uint8_t staId,
1283 struct cdf_mac_addr *pPeerMacAddress,
1284 tSirBssDescription *pBssDesc)
1285{
1286 CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
1287 struct ol_txrx_desc_type staDesc = { 0 };
1288 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1289
1290 if (NULL == pBssDesc)
1291 return CDF_STATUS_E_FAILURE;
1292
1293 /* Get the Station ID from the one saved during the association */
1294 staDesc.sta_id = staId;
1295
1296 /* set the QoS field appropriately */
1297 if (hdd_wmm_is_active(pAdapter))
1298 staDesc.is_qos_enabled = 1;
1299 else
1300 staDesc.is_qos_enabled = 0;
1301
1302#ifdef FEATURE_WLAN_WAPI
1303 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1304 pAdapter->wapi_info.fIsWapiSta);
1305 if (pAdapter->wapi_info.fIsWapiSta)
1306 staDesc.is_wapi_supported = 1;
1307 else
1308 staDesc.is_wapi_supported = 0;
1309#endif /* FEATURE_WLAN_WAPI */
1310
1311 cdf_status = ol_txrx_register_peer(hdd_rx_packet_cbk,
1312 &staDesc);
1313 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1314 hddLog(LOGW,
1315 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
1316 cdf_status, cdf_status);
1317 return cdf_status;
1318 }
1319
1320 if (!pRoamInfo->fAuthRequired) {
1321 /*
1322 * Connections that do not need Upper layer auth, transition
1323 * TLSHIM directly to 'Authenticated' state
1324 */
1325 cdf_status =
1326 hdd_change_peer_state(pAdapter, staDesc.sta_id,
1327 ol_txrx_peer_state_auth,
1328#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1329 pRoamInfo->roamSynchInProgress
1330#else
1331 false
1332#endif
1333 );
1334
1335 hdd_conn_set_authenticated(pAdapter, true);
1336 } else {
1337 hddLog(LOG3,
1338 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1339 pHddStaCtx->conn_info.staId[0]);
1340 cdf_status =
1341 hdd_change_peer_state(pAdapter, staDesc.sta_id,
1342 ol_txrx_peer_state_conn,
1343#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1344 pRoamInfo->roamSynchInProgress
1345#else
1346 false
1347#endif
1348 );
1349 hdd_conn_set_authenticated(pAdapter, false);
1350 }
1351 return cdf_status;
1352}
1353
1354/**
1355 * hdd_send_re_assoc_event() - send reassoc event
1356 * @dev: pointer to net device
1357 * @pAdapter: pointer to adapter
1358 * @pCsrRoamInfo: pointer to roam info
1359 * @reqRsnIe: pointer to RSN Information element
1360 * @reqRsnLength: length of RSN IE
1361 *
1362 * Return: none
1363 */
1364static void hdd_send_re_assoc_event(struct net_device *dev,
1365 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1366 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1367{
1368 unsigned int len = 0;
1369 u8 *pFTAssocRsp = NULL;
1370 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001371 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001372 uint32_t rspRsnLength = 0;
1373 struct ieee80211_channel *chan;
1374 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1375 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1376 uint8_t *buf_ptr, ssid_ie_len;
1377 struct cfg80211_bss *bss = NULL;
1378 uint8_t *final_req_ie = NULL;
1379 tCsrRoamConnectedProfile roam_profile;
1380 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1381
1382 if (!rspRsnIe) {
1383 hddLog(LOGE, FL("Unable to allocate RSN IE"));
1384 return;
1385 }
1386
Naveen Rawat14298b92015-11-25 16:27:41 -08001387 if (!assoc_req_ies) {
1388 hdd_err("Unable to allocate Assoc Req IE");
1389 return;
1390 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001391 if (pCsrRoamInfo == NULL) {
1392 hddLog(LOGE, FL("Invalid CSR roam info"));
1393 goto done;
1394 }
1395
1396 if (pCsrRoamInfo->nAssocRspLength == 0) {
1397 hddLog(LOGE, FL("Invalid assoc response length"));
1398 goto done;
1399 }
1400
1401 pFTAssocRsp =
1402 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1403 pCsrRoamInfo->nAssocReqLength);
1404 if (pFTAssocRsp == NULL)
1405 goto done;
1406
1407 /* pFTAssocRsp needs to point to the IEs */
1408 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1409 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1410 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1411
1412 /*
1413 * Active session count is decremented upon disconnection, but during
1414 * roaming, there is no disconnect indication and hence active session
1415 * count is not decremented.
1416 * After roaming is completed, active session count is incremented
1417 * as a part of connect indication but effectively after roaming the
1418 * active session count should still be the same and hence upon
1419 * successful reassoc decrement the active session count here.
1420 */
1421 cds_decr_session_set_pcl(
1422 pHddCtx, pAdapter->device_mode,
1423 pAdapter->sessionId);
1424
1425 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1426 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1427 rspRsnLength = len;
1428 cdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1429 cdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
1430
1431 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1432 (int)pCsrRoamInfo->pBssDesc->channelId);
1433 cdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
1434 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1435 &roam_profile);
1436 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1437 pCsrRoamInfo->bssid.bytes,
1438 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
1439 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
1440
1441 if (bss == NULL)
1442 hddLog(LOGE, FL("Get BSS returned NULL"));
1443 buf_ptr = buf_ssid_ie;
1444 *buf_ptr = SIR_MAC_SSID_EID;
1445 buf_ptr++;
1446 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1447 buf_ptr++;
1448 cdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
1449 roam_profile.SSID.length);
1450 ssid_ie_len = 2 + roam_profile.SSID.length;
1451 hddLog(LOG2, FL("SSIDIE:"));
1452 hddLog(CDF_TRACE_LEVEL_DEBUG, buf_ssid_ie, ssid_ie_len);
1453 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1454 if (final_req_ie == NULL)
1455 goto done;
1456 buf_ptr = final_req_ie;
1457 cdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
1458 buf_ptr += ssid_ie_len;
1459 cdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1460 cdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1461 cdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
1462 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
1463 hddLog(LOG2, FL("Req RSN IE:"));
1464 hddLog(CDF_TRACE_LEVEL_DEBUG, final_req_ie,
1465 (ssid_ie_len + reqRsnLength));
1466 cfg80211_roamed_bss(dev, bss,
1467 final_req_ie, (ssid_ie_len + reqRsnLength),
1468 rspRsnIe, rspRsnLength, GFP_KERNEL);
1469
Naveen Rawat14298b92015-11-25 16:27:41 -08001470 cdf_mem_copy(assoc_req_ies,
1471 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1472 pCsrRoamInfo->nAssocReqLength);
1473
1474 hdd_notice("ReAssoc Req IE dump");
1475 CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_DEBUG,
1476 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1477
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001478 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001479 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1480 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001481 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001482done:
1483 sme_roam_free_connect_profile(hal_handle, &roam_profile);
1484 if (final_req_ie)
1485 kfree(final_req_ie);
1486 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001487 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001488}
1489
1490/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301491 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
1492 *
1493 * Return: roam sync status if roaming offloaded else false
1494 */
1495#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1496static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
1497{
1498 return roaminfo->roamSynchInProgress;
1499}
1500#else
1501static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
1502{
1503 return false;
1504}
1505#endif
1506
1507
1508/**
1509 * hdd_change_sta_state_authenticated()-
1510 * This function changes STA state to authenticated
1511 * @adapter: pointer to the adapter structure.
1512 * @roaminfo: pointer to the RoamInfo structure.
1513 *
1514 * This is called from hdd_RoamSetKeyCompleteHandler
1515 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1516 *
1517 * Return: 0 on success and errno on failure
1518 */
1519static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1520 tCsrRoamInfo *roaminfo)
1521{
1522 int ret;
1523 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1524
1525 hddLog(LOG1,
1526 "Changing TL state to AUTHENTICATED for StaId= %d",
1527 hddstactx->conn_info.staId[0]);
1528
1529 /* Connections that do not need Upper layer authentication,
1530 * transition TL to 'Authenticated' state after the keys are set
1531 */
1532 ret = hdd_change_peer_state(adapter,
1533 hddstactx->conn_info.staId[0],
1534 ol_txrx_peer_state_auth,
1535 hdd_is_roam_sync_in_progress(roaminfo));
1536 hdd_conn_set_authenticated(adapter, true);
1537 if ((WLAN_HDD_INFRA_STATION == adapter->device_mode) ||
1538 (WLAN_HDD_P2P_CLIENT == adapter->device_mode)) {
1539 sme_ps_enable_auto_ps_timer(
1540 WLAN_HDD_GET_HAL_CTX(adapter),
1541 adapter->sessionId,
1542 hddstactx->hdd_ReassocScenario);
1543 }
1544
1545 return ret;
1546}
1547
1548/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001549 * hdd_roam_set_key_complete_handler() - Update the security parameters
1550 * @pAdapter: pointer to adapter
1551 * @pRoamInfo: pointer to roam info
1552 * @roamId: roam id
1553 * @roamStatus: roam status
1554 * @roamResult: roam result
1555 *
1556 * Return: CDF_STATUS enumeration
1557 */
1558static CDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
1559 tCsrRoamInfo *pRoamInfo,
1560 uint32_t roamId,
1561 eRoamCmdStatus roamStatus,
1562 eCsrRoamResult roamResult)
1563{
1564 eCsrEncryptionType connectedCipherAlgo;
1565 bool fConnected = false;
1566 CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
1567 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1568 ENTER();
1569
1570 if (NULL == pRoamInfo) {
1571 hddLog(LOG2, FL("pRoamInfo is NULL"));
1572 return CDF_STATUS_E_FAILURE;
1573 }
1574 /*
1575 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1576 * then go to 'authenticated'. For all other authentication types
1577 * (those that do not require upper layer authentication) we can put TL
1578 * directly into 'authenticated' state.
1579 */
1580 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1581 MAC_ADDRESS_STR, roamStatus, roamResult,
1582 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1583
1584 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1585 &connectedCipherAlgo);
1586 if (fConnected) {
1587 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
1588 uint8_t staId;
1589
1590 if (cdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
1591 pHddStaCtx->roam_info.roamingState =
1592 HDD_ROAM_STATE_NONE;
1593 } else {
1594 cdf_status = hdd_ibss_get_sta_id(
1595 pHddStaCtx,
1596 &pRoamInfo->peerMac,
1597 &staId);
1598 if (CDF_STATUS_SUCCESS == cdf_status) {
1599 hddLog(LOG2,
1600 "WLAN TL STA Ptk Installed for STAID=%d",
1601 staId);
1602 pHddStaCtx->roam_info.roamingState =
1603 HDD_ROAM_STATE_NONE;
1604 }
1605 }
1606 } else {
1607 /*
1608 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301609 * HDD later.This routine is invoked twice.
1610 * 1)set PTK 2)set GTK.The following if
1611 * statement will be TRUE when setting GTK.
1612 * At this time we don't handle the state in detail.
1613 * Related CR: 174048 - TL not in authenticated state
1614 */
1615 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult)
1616 pHddStaCtx->conn_info.gtk_installed = true;
1617 else
1618 pHddStaCtx->conn_info.ptk_installed = true;
1619
1620 /* In WPA case move STA to authenticated when
1621 * ptk is installed.Earlier in WEP case STA
1622 * was moved to AUTHENTICATED prior to setting
1623 * the unicast key and it was resulting in sending
1624 * few un-encrypted packet. Now in WEP case
1625 * STA state will be moved to AUTHENTICATED
1626 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301628 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1629 eCSR_ENCRYPT_TYPE_WEP40) ||
1630 (pHddStaCtx->conn_info.ucEncryptionType ==
1631 eCSR_ENCRYPT_TYPE_WEP104) ||
1632 (pHddStaCtx->conn_info.ucEncryptionType ==
1633 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1634 (pHddStaCtx->conn_info.ucEncryptionType ==
1635 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1636 if (pHddStaCtx->conn_info.gtk_installed &&
1637 pHddStaCtx->conn_info.ptk_installed)
1638 cdf_status =
1639 hdd_change_sta_state_authenticated(pAdapter,
1640 pRoamInfo);
1641 } else if (pHddStaCtx->conn_info.ptk_installed) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642 cdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301643 hdd_change_sta_state_authenticated(pAdapter,
1644 pRoamInfo);
1645 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001646
Govind Singhedc5cda2015-10-23 17:11:35 +05301647 if (pHddStaCtx->conn_info.gtk_installed &&
1648 pHddStaCtx->conn_info.ptk_installed) {
1649 pHddStaCtx->conn_info.gtk_installed = false;
1650 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001651 }
1652
1653 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301654 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655 }
1656 } else {
1657 /*
1658 * possible disassoc after issuing set key and waiting
1659 * set key complete.
1660 */
1661 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1662 }
1663
1664 EXIT();
1665 return CDF_STATUS_SUCCESS;
1666}
1667
1668/**
1669 * hdd_perform_roam_set_key_complete() - perform set key complete
1670 * @pAdapter: pointer to adapter
1671 *
1672 * Return: none
1673 */
1674void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1675{
1676 CDF_STATUS cdf_ret_status = CDF_STATUS_SUCCESS;
1677 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1678 tCsrRoamInfo roamInfo;
1679 roamInfo.fAuthRequired = false;
1680 cdf_mem_copy(roamInfo.bssid.bytes,
1681 pHddStaCtx->roam_info.bssid, CDF_MAC_ADDR_SIZE);
1682 cdf_mem_copy(roamInfo.peerMac.bytes,
1683 pHddStaCtx->roam_info.peerMac, CDF_MAC_ADDR_SIZE);
1684
1685 cdf_ret_status =
1686 hdd_roam_set_key_complete_handler(pAdapter,
1687 &roamInfo,
1688 pHddStaCtx->roam_info.roamId,
1689 pHddStaCtx->roam_info.roamStatus,
1690 eCSR_ROAM_RESULT_AUTHENTICATED);
1691 if (cdf_ret_status != CDF_STATUS_SUCCESS)
1692 hddLog(LOGE, FL("Set Key complete failure"));
1693
1694 pHddStaCtx->roam_info.deferKeyComplete = false;
1695}
1696
1697/**
1698 * hdd_association_completion_handler() - association completion handler
1699 * @pAdapter: pointer to adapter
1700 * @pRoamInfo: pointer to roam info
1701 * @roamId: roam id
1702 * @roamStatus: roam status
1703 * @roamResult: roam result
1704 *
1705 * Return: CDF_STATUS enumeration
1706 */
1707static CDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
1708 tCsrRoamInfo *pRoamInfo,
1709 uint32_t roamId,
1710 eRoamCmdStatus roamStatus,
1711 eCsrRoamResult roamResult)
1712{
1713 struct net_device *dev = pAdapter->dev;
1714 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1715 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1716 CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
1717 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1718 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
1719#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) || \
1720defined(WLAN_FEATURE_VOWIFI_11R)
1721 int ft_carrier_on = false;
1722#endif
1723 bool hddDisconInProgress = false;
1724 unsigned long rc;
1725
1726 if (!pHddCtx) {
1727 hdd_err("HDD context is NULL");
1728 return CDF_STATUS_E_FAILURE;
1729 }
1730
1731#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1732 if (pRoamInfo && pRoamInfo->roamSynchInProgress) {
1733 /* change logging before release */
1734 hddLog(LOG3, "LFR3:hdd_association_completion_handler");
1735 }
1736#endif
1737
1738 /* HDD has initiated disconnect, do not send connect result indication
1739 * to kernel as it will be handled by __cfg80211_disconnect.
1740 */
1741 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1742 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1743 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1744 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1745 hddDisconInProgress = true;
1746 }
1747
1748 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1749 if (NULL == pRoamInfo) {
1750 hddLog(LOGE, FL("pRoamInfo is NULL"));
1751 return CDF_STATUS_E_FAILURE;
1752 }
1753 if (!hddDisconInProgress) {
1754 hddLog(LOG1, FL("Set HDD connState to eConnectionState_Associated"));
1755 hdd_conn_set_connection_state(pAdapter,
1756 eConnectionState_Associated);
1757 }
1758 /* Save the connection info from CSR... */
1759 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1760 eCSR_BSS_TYPE_INFRASTRUCTURE);
1761#ifdef FEATURE_WLAN_WAPI
1762 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1763 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1764 || pRoamInfo->u.pConnectedProfile->AuthType ==
1765 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1766 pAdapter->wapi_info.fIsWapiSta = 1;
1767 } else {
1768 pAdapter->wapi_info.fIsWapiSta = 0;
1769 }
1770#endif /* FEATURE_WLAN_WAPI */
1771
1772 /* Indicate 'connect' status to user space */
1773 hdd_send_association_event(dev, pRoamInfo);
1774
1775 if (cds_is_mcc_in_24G(pHddCtx)) {
1776 if (pHddCtx->miracast_value)
1777 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1778 }
1779
1780 /* Initialize the Linkup event completion variable */
1781 INIT_COMPLETION(pAdapter->linkup_event_var);
1782
1783 /*
1784 * Sometimes Switching ON the Carrier is taking time to activate
1785 * the device properly. Before allowing any packet to go up to
1786 * the application, device activation has to be ensured for
1787 * proper queue mapping by the kernel. we have registered net
1788 * device notifier for device change notification. With this we
1789 * will come to know that the device is getting
1790 * activated properly.
1791 */
1792#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
1793defined(FEATURE_WLAN_LFR)
1794 if (pHddStaCtx->ft_carrier_on == false) {
1795#endif
1796 /*
1797 * Enable Linkup Event Servicing which allows the net device
1798 * notifier to set the linkup event variable.
1799 */
1800 pAdapter->isLinkUpSvcNeeded = true;
1801
1802 /*
1803 * Enable Linkup Event Servicing which allows the net device
1804 * notifier to set the linkup event variable.
1805 */
1806 pAdapter->isLinkUpSvcNeeded = true;
1807
1808 /* Switch on the Carrier to activate the device */
1809 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_CARRIER_ON,
1810 WLAN_CONTROL_PATH);
1811
1812 /*
1813 * Wait for the Link to up to ensure all the queues are set
1814 * properly by the kernel.
1815 */
1816 rc = wait_for_completion_timeout(&pAdapter->
1817 linkup_event_var,
1818 msecs_to_jiffies
1819 (ASSOC_LINKUP_TIMEOUT));
1820 if (!rc)
1821 hddLog(LOGW, FL("Warning:ASSOC_LINKUP_TIMEOUT"));
1822
1823 /*
1824 * Disable Linkup Event Servicing - no more service required
1825 * from the net device notifier call.
1826 */
1827 pAdapter->isLinkUpSvcNeeded = false;
1828#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
1829defined(FEATURE_WLAN_LFR)
1830 } else {
1831 pHddStaCtx->ft_carrier_on = false;
1832 ft_carrier_on = true;
1833 }
1834#endif
1835 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1836 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1837 else
1838 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1839 pRoamInfo->staId);
1840
1841 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1842
1843 if (hdd_ipa_is_enabled(pHddCtx))
1844 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1845 WLAN_STA_CONNECT,
1846 pRoamInfo->bssid.bytes);
1847
1848#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1849 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1850#endif
1851
1852 cds_check_concurrent_intf_and_restart_sap(pHddCtx,
1853 pHddStaCtx,
1854 pAdapter);
1855
1856#ifdef FEATURE_WLAN_TDLS
1857 wlan_hdd_tdls_connection_callback(pAdapter);
1858#endif
1859
1860#ifdef QCA_PKT_PROTO_TRACE
1861 /* STA Associated, update into trace buffer */
1862 if (pHddCtx->config->gEnableDebugLog)
1863 cds_pkt_trace_buf_update("ST:ASSOC");
1864#endif /* QCA_PKT_PROTO_TRACE */
1865 /*
1866 * For reassoc, the station is already registered, all we need
1867 * is to change the state of the STA in TL.
1868 * If authentication is required (WPA/WPA2/DWEP), change TL to
1869 * CONNECTED instead of AUTHENTICATED.
1870 */
1871 if (!pRoamInfo->fReassocReq) {
1872 struct cfg80211_bss *bss;
1873#ifdef WLAN_FEATURE_VOWIFI_11R
1874 u8 *pFTAssocRsp = NULL;
1875 unsigned int assocRsplen = 0;
1876 u8 *pFTAssocReq = NULL;
1877 unsigned int assocReqlen = 0;
1878 struct ieee80211_channel *chan;
1879#endif
1880 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1881 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1882
1883 /* add bss_id to cfg80211 data base */
1884 bss =
1885 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1886 pRoamInfo);
1887 if (NULL == bss) {
1888 pr_err("wlan: Not able to create BSS entry\n");
1889 wlan_hdd_netif_queue_control(pAdapter,
1890 WLAN_NETIF_CARRIER_OFF,
1891 WLAN_CONTROL_PATH);
1892 return CDF_STATUS_E_FAILURE;
1893 }
1894#ifdef WLAN_FEATURE_VOWIFI_11R
1895 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1896 eCSR_AUTH_TYPE_FT_RSN
1897 || pRoamInfo->u.pConnectedProfile->AuthType ==
1898 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1899
1900 /* Association Response */
1901 pFTAssocRsp =
1902 (u8 *) (pRoamInfo->pbFrames +
1903 pRoamInfo->nBeaconLength +
1904 pRoamInfo->nAssocReqLength);
1905 if (pFTAssocRsp != NULL) {
1906 /*
1907 * pFTAssocRsp needs to point to the IEs
1908 */
1909 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1910 hddLog(LOG1,
1911 FL("AssocRsp is now at %02x%02x"),
1912 (unsigned int)pFTAssocRsp[0],
1913 (unsigned int)pFTAssocRsp[1]);
1914 assocRsplen =
1915 pRoamInfo->nAssocRspLength -
1916 FT_ASSOC_RSP_IES_OFFSET;
1917 } else {
1918 hddLog(LOGE, FL("AssocRsp is NULL"));
1919 assocRsplen = 0;
1920 }
1921
1922 /* Association Request */
1923 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1924 pRoamInfo->nBeaconLength);
1925 if (pFTAssocReq != NULL) {
1926 if (!ft_carrier_on) {
1927 /*
1928 * pFTAssocReq needs to point to
1929 * the IEs
1930 */
1931 pFTAssocReq +=
1932 FT_ASSOC_REQ_IES_OFFSET;
1933 hddLog(LOG1,
1934 FL("pFTAssocReq is now at %02x%02x"),
1935 (unsigned int)
1936 pFTAssocReq[0],
1937 (unsigned int)
1938 pFTAssocReq[1]);
1939 assocReqlen =
1940 pRoamInfo->nAssocReqLength -
1941 FT_ASSOC_REQ_IES_OFFSET;
1942 } else {
1943 /*
1944 * This should contain only the
1945 * FTIEs
1946 */
1947 assocReqlen =
1948 pRoamInfo->nAssocReqLength;
1949 }
1950 } else {
1951 hddLog(LOGE, FL("AssocReq is NULL"));
1952 assocReqlen = 0;
1953 }
1954
1955 if (ft_carrier_on) {
1956 if (!hddDisconInProgress) {
1957 /*
1958 * After roaming is completed,
1959 * active session count is
1960 * incremented as a part of
1961 * connect indication but
1962 * effectively the active
1963 * session count should still
1964 * be the same and hence upon
1965 * successful reassoc
1966 * decrement the active session
1967 * count here.
1968 */
1969 cds_decr_session_set_pcl
1970 (pHddCtx,
1971 pAdapter->device_mode,
1972 pAdapter->sessionId);
1973 hddLog(LOG1,
1974 FL("ft_carrier_on is %d, sending roamed indication"),
1975 ft_carrier_on);
1976 chan =
1977 ieee80211_get_channel
1978 (pAdapter->wdev.wiphy,
1979 (int)pRoamInfo->pBssDesc->
1980 channelId);
1981 hddLog(LOG1,
1982 "assocReqlen %d assocRsplen %d",
1983 assocReqlen,
1984 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08001985
1986 hdd_notice(
1987 "Reassoc Req IE dump");
1988 CDF_TRACE_HEX_DUMP(
1989 CDF_MODULE_ID_HDD,
1990 CDF_TRACE_LEVEL_DEBUG,
1991 pFTAssocReq,
1992 assocReqlen);
1993
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001994 cfg80211_roamed(dev, chan,
1995 pRoamInfo->
1996 bssid.bytes,
1997 pFTAssocReq,
1998 assocReqlen,
1999 pFTAssocRsp,
2000 assocRsplen,
2001 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08002002 wlan_hdd_send_roam_auth_event(
2003 pHddCtx,
2004 pRoamInfo->bssid.bytes,
2005 pFTAssocReq,
2006 assocReqlen,
2007 pFTAssocRsp,
2008 assocRsplen,
2009 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002010 }
2011 if (sme_get_ftptk_state
2012 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2013 pAdapter->sessionId)) {
2014 sme_set_ftptk_state
2015 (WLAN_HDD_GET_HAL_CTX
2016 (pAdapter),
2017 pAdapter->sessionId,
2018 false);
2019 pRoamInfo->fAuthRequired =
2020 false;
2021
2022 cdf_mem_copy(pHddStaCtx->
2023 roam_info.bssid,
2024 pRoamInfo->bssid.bytes,
2025 CDF_MAC_ADDR_SIZE);
2026 cdf_mem_copy(pHddStaCtx->
2027 roam_info.peerMac,
2028 pRoamInfo->peerMac.bytes,
2029 CDF_MAC_ADDR_SIZE);
2030 pHddStaCtx->roam_info.roamId =
2031 roamId;
2032 pHddStaCtx->roam_info.
2033 roamStatus = roamStatus;
2034 pHddStaCtx->roam_info.
2035 deferKeyComplete = true;
2036 }
2037 } else if (!hddDisconInProgress) {
2038 hddLog(LOG1,
2039 FL("ft_carrier_on is %d, sending connect indication"),
2040 ft_carrier_on);
2041 cfg80211_connect_result(dev,
2042 pRoamInfo->
2043 bssid.bytes,
2044 pFTAssocReq,
2045 assocReqlen,
2046 pFTAssocRsp,
2047 assocRsplen,
2048 WLAN_STATUS_SUCCESS,
2049 GFP_KERNEL);
2050 }
2051 } else
2052#endif
2053 {
2054 /*
2055 * wpa supplicant expecting WPA/RSN IE in
2056 * connect result.
2057 */
2058 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2059 (pAdapter),
2060 pAdapter->sessionId,
2061 &reqRsnLength,
2062 reqRsnIe);
2063
2064 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2065 (pAdapter),
2066 pAdapter->sessionId,
2067 &rspRsnLength,
2068 rspRsnIe);
2069 if (!hddDisconInProgress) {
2070#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2071 if (ft_carrier_on)
2072 hdd_send_re_assoc_event(dev,
2073 pAdapter,
2074 pRoamInfo,
2075 reqRsnIe,
2076 reqRsnLength);
2077 else
2078#endif /* FEATURE_WLAN_ESE */
2079
2080 {
2081 hddLog(LOG1,
2082 FL("sending connect indication to nl80211:for bssid "
2083 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302084 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002085 MAC_ADDR_ARRAY
2086 (pRoamInfo->bssid.bytes),
2087 roamResult, roamStatus);
2088
2089 /* inform connect result to nl80211 */
2090 cfg80211_connect_result(dev,
2091 pRoamInfo->
2092 bssid.bytes,
2093 reqRsnIe,
2094 reqRsnLength,
2095 rspRsnIe,
2096 rspRsnLength,
2097 WLAN_STATUS_SUCCESS,
2098 GFP_KERNEL);
2099 }
2100 }
2101 }
2102 if (!hddDisconInProgress) {
2103 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002104 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002105 bss);
2106
2107 /*
2108 * Perform any WMM-related association
2109 * processing.
2110 */
2111 hdd_wmm_assoc(pAdapter, pRoamInfo,
2112 eCSR_BSS_TYPE_INFRASTRUCTURE);
2113
2114 /*
2115 * Start the Queue - Start tx queues before
2116 * hdd_roam_register_sta, since
2117 * hdd_roam_register_sta will flush any cached
2118 * data frames immediately.
2119 */
2120 hddLog(LOG1, FL("Enabling queues"));
2121 wlan_hdd_netif_queue_control(pAdapter,
2122 WLAN_WAKE_ALL_NETIF_QUEUE,
2123 WLAN_CONTROL_PATH);
2124
2125 /*
2126 * Register the Station with TL after associated
2127 */
2128 cdf_status = hdd_roam_register_sta(pAdapter,
2129 pRoamInfo,
2130 pHddStaCtx->
2131 conn_info.
2132 staId[0],
2133 NULL,
2134 pRoamInfo->
2135 pBssDesc);
2136 }
2137 } else {
2138 /*
2139 * wpa supplicant expecting WPA/RSN IE in connect result
2140 * in case of reassociation also need to indicate it to
2141 * supplicant.
2142 */
2143 csr_roam_get_wpa_rsn_req_ie(
2144 WLAN_HDD_GET_HAL_CTX(pAdapter),
2145 pAdapter->sessionId,
2146 &reqRsnLength, reqRsnIe);
2147
2148 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2149 reqRsnIe, reqRsnLength);
2150 /* Reassoc successfully */
2151 if (pRoamInfo->fAuthRequired) {
2152 cdf_status =
2153 hdd_change_peer_state(pAdapter,
2154 pHddStaCtx->conn_info.staId[0],
2155 ol_txrx_peer_state_conn,
2156#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2157 pRoamInfo->roamSynchInProgress
2158#else
2159 false
2160#endif
2161 );
2162 hdd_conn_set_authenticated(pAdapter, false);
2163 } else {
2164 hddLog(LOG2,
2165 FL("staId: %d Changing TL state to AUTHENTICATED"),
2166 pHddStaCtx->conn_info.staId[0]);
2167 cdf_status =
2168 hdd_change_peer_state(pAdapter,
2169 pHddStaCtx->conn_info.staId[0],
2170 ol_txrx_peer_state_auth,
2171#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2172 pRoamInfo->roamSynchInProgress
2173#else
2174 false
2175#endif
2176 );
2177 hdd_conn_set_authenticated(pAdapter, true);
2178 }
2179
2180 if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
2181 /*
2182 * Perform any WMM-related association
2183 * processing
2184 */
2185 hdd_wmm_assoc(pAdapter, pRoamInfo,
2186 eCSR_BSS_TYPE_INFRASTRUCTURE);
2187 }
2188
2189 /* Start the tx queues */
2190#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2191 if (pRoamInfo->roamSynchInProgress)
2192 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2193#endif
2194 hddLog(LOG1, FL("Enabling queues"));
2195 wlan_hdd_netif_queue_control(pAdapter,
2196 WLAN_WAKE_ALL_NETIF_QUEUE,
2197 WLAN_CONTROL_PATH);
2198 }
2199
2200 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2201 hddLog(LOGE,
2202 "STA register with TL failed. status(=%d) [%08X]",
2203 cdf_status, cdf_status);
2204 }
2205#ifdef WLAN_FEATURE_11W
2206 cdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
2207 sizeof(pAdapter->hdd_stats.hddPmfStats));
2208#endif
2209 } else {
2210 hdd_wext_state_t *pWextState =
2211 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2212 if (pRoamInfo)
2213 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302214 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2216 roamResult, roamStatus);
2217 else
2218 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302219 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002220 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2221 roamResult, roamStatus);
2222
2223 /*
2224 * CR465478: Only send up a connection failure result when CSR
2225 * has completed operation - with a ASSOCIATION_FAILURE status.
2226 */
2227 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2228 && !hddDisconInProgress) {
2229 if (pRoamInfo)
2230 hddLog(LOGE,
2231 FL("send connect failure to nl80211: for bssid "
2232 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302233 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002234 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302235 roamResult, roamStatus,
2236 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237 else
2238 hddLog(LOGE,
2239 FL("connect failed: for bssid "
2240 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302241 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002242 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2243 roamResult, roamStatus);
2244
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002245 /* inform association failure event to nl80211 */
2246 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2247 roamResult) {
2248 if (pRoamInfo)
2249 cfg80211_connect_result(dev,
2250 pRoamInfo->bssid.bytes,
2251 NULL, 0, NULL, 0,
2252 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2253 GFP_KERNEL);
2254 else
2255 cfg80211_connect_result(dev,
2256 pWextState->req_bssId.bytes,
2257 NULL, 0, NULL, 0,
2258 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2259 GFP_KERNEL);
2260 } else {
2261 if (pRoamInfo) {
2262 eCsrAuthType authType =
2263 pWextState->roamProfile.AuthType.
2264 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302265 eCsrEncryptionType encryption_type =
2266 pWextState->roamProfile.
2267 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302269 (((authType ==
2270 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002271 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302272 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2273 ((encryption_type ==
2274 eCSR_ENCRYPT_TYPE_WEP40) ||
2275 (encryption_type ==
2276 eCSR_ENCRYPT_TYPE_WEP104) ||
2277 (encryption_type ==
2278 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2279 (encryption_type ==
2280 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002281 /*
2282 * In case of OPEN-WEP or SHARED-WEP
2283 * authentication, send exact protocol
2284 * reason code. This enables user
2285 * applications to reconnect the station
2286 * with correct configuration.
2287 */
2288 cfg80211_connect_result(dev,
2289 pRoamInfo->bssid.bytes, NULL, 0,
2290 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302291 (isWep &&
2292 pRoamInfo->reasonCode) ?
2293 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002294 WLAN_STATUS_UNSPECIFIED_FAILURE,
2295 GFP_KERNEL);
2296 } else
2297 cfg80211_connect_result(dev,
2298 pWextState->req_bssId.bytes,
2299 NULL, 0, NULL, 0,
2300 WLAN_STATUS_UNSPECIFIED_FAILURE,
2301 GFP_KERNEL);
2302 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302303 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304 }
2305
2306 if (pRoamInfo) {
2307 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2308 pRoamInfo->statusCode)
2309 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2310 pRoamInfo->statusCode)
2311 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2312 pRoamInfo->statusCode)) {
2313 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2314 pRoamInfo);
2315 }
2316 }
2317
2318 /*
2319 * Set connection state to eConnectionState_NotConnected only
2320 * when CSR has completed operation - with a
2321 * ASSOCIATION_FAILURE status.
2322 */
2323 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2324 && !hddDisconInProgress) {
2325 hddLog(LOG1,
2326 FL("state to eConnectionState_NotConnected"));
2327 hdd_conn_set_connection_state(pAdapter,
2328 eConnectionState_NotConnected);
2329 }
2330 hdd_wmm_init(pAdapter);
2331
2332 hddLog(LOG1, FL("Disabling queues"));
2333 wlan_hdd_netif_queue_control(pAdapter,
2334 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2335 WLAN_CONTROL_PATH);
2336 }
2337
2338 if (CDF_STATUS_SUCCESS != cds_check_and_restart_sap(pHddCtx,
2339 roamResult, pHddStaCtx))
2340 return CDF_STATUS_E_FAILURE;
2341
2342 cds_force_sap_on_scc(pHddCtx, roamResult);
2343
2344 return CDF_STATUS_SUCCESS;
2345}
2346
2347/**
2348 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2349 * @pAdapter: pointer to adapter
2350 * @pRoamInfo: pointer to roam info
2351 * @roamId: roam id
2352 * @roamStatus: roam status
2353 * @roamResult: roam result
2354 *
2355 * Here we update the status of the Ibss when we receive information that we
2356 * have started/joined an ibss session.
2357 *
2358 * Return: none
2359 */
2360static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2361 tCsrRoamInfo *pRoamInfo,
2362 uint32_t roamId,
2363 eRoamCmdStatus roamStatus,
2364 eCsrRoamResult roamResult)
2365{
2366 hddLog(LOG1, "%s: id %d, status %d, result %d",
2367 pAdapter->dev->name, roamId, roamStatus, roamResult);
2368
2369 switch (roamResult) {
2370 /* both IBSS Started and IBSS Join should come in here. */
2371 case eCSR_ROAM_RESULT_IBSS_STARTED:
2372 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2373 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2374 {
2375 hdd_context_t *pHddCtx =
2376 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302377 hdd_station_ctx_t *hdd_sta_ctx =
2378 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002379 struct cdf_mac_addr broadcastMacAddr =
2380 CDF_MAC_ADDR_BROADCAST_INITIALIZER;
2381
2382 if (NULL == pRoamInfo) {
2383 CDF_ASSERT(0);
2384 return;
2385 }
2386
2387 /* When IBSS Started comes from CSR, we need to move
2388 * connection state to IBSS Disconnected (meaning no peers
2389 * are in the IBSS).
2390 */
2391 hddLog(LOG1,
2392 FL("Set HDD connState to eConnectionState_IbssDisconnected"));
2393 hdd_conn_set_connection_state(pAdapter,
2394 eConnectionState_IbssDisconnected);
2395 /* notify wmm */
2396 hdd_wmm_connect(pAdapter, pRoamInfo,
2397 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302398
2399 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2400
2401 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002402 pAdapter;
2403 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302404 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002405 &broadcastMacAddr,
2406 pRoamInfo->pBssDesc);
2407
2408 if (pRoamInfo->pBssDesc) {
2409 struct cfg80211_bss *bss;
2410#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2411 struct ieee80211_channel *chan;
2412 int chan_no;
2413 unsigned int freq;
2414#endif
2415 /* we created the IBSS, notify supplicant */
2416 hddLog(LOG1,
2417 FL("%s: created ibss " MAC_ADDRESS_STR),
2418 pAdapter->dev->name,
2419 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2420
2421 /* we must first give cfg80211 the BSS information */
2422 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2423 pRoamInfo);
2424 if (NULL == bss) {
2425 hddLog(LOGE,
2426 FL("%s: unable to create IBSS entry"),
2427 pAdapter->dev->name);
2428 return;
2429 }
2430 hddLog(LOG1, FL("Enabling queues"));
2431 wlan_hdd_netif_queue_control(pAdapter,
2432 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2433 WLAN_CONTROL_PATH);
2434
2435#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2436 chan_no = pRoamInfo->pBssDesc->channelId;
2437
2438 if (chan_no <= 14)
2439 freq = ieee80211_channel_to_frequency(chan_no,
2440 IEEE80211_BAND_2GHZ);
2441 else
2442 freq = ieee80211_channel_to_frequency(chan_no,
2443 IEEE80211_BAND_5GHZ);
2444
2445 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2446
2447 if (chan)
2448 cfg80211_ibss_joined(pAdapter->dev,
2449 bss->bssid, chan,
2450 GFP_KERNEL);
2451 else
2452 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2453 pAdapter->dev->name,
2454 (int)pRoamInfo->pBssDesc->channelId);
2455#else
2456 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2457 GFP_KERNEL);
2458#endif
2459 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002460 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002461 bss);
2462 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002463 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
2464 cds_incr_active_session(pHddCtx, pAdapter->device_mode,
2465 pAdapter->sessionId);
2466 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2467 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
2468 cds_update_connection_info(pHddCtx,
2469 pAdapter->sessionId);
2470 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002471 break;
2472 }
2473
2474 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2475 {
2476 hddLog(LOGE,
2477 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2478 break;
2479 }
2480
2481 default:
2482 hddLog(LOGE, FL("%s: unexpected result %d"),
2483 pAdapter->dev->name, (int)roamResult);
2484 break;
2485 }
2486
2487 return;
2488}
2489
2490/**
2491 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2492 * @pHddStaCtx: pointer to global HDD station context
2493 * @staId: station id
2494 * @peerMacAddress: pointer to peer MAC address
2495 *
2496 * This information is passed to iwconfig later. The peer that joined
2497 * last is passed as information to iwconfig.
2498 *
2499 * Return:
2500 * true if we add MAX_IBSS_PEERS or less STA
2501 * false otherwise.
2502 */
2503static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
2504 struct cdf_mac_addr *peerMacAddress)
2505{
2506 bool fSuccess = false;
2507 int idx = 0;
2508
2509 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2510 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2511 pHddStaCtx->conn_info.staId[idx] = staId;
2512
2513 cdf_copy_macaddr(&pHddStaCtx->conn_info.
2514 peerMacAddress[idx], peerMacAddress);
2515
2516 fSuccess = true;
2517 break;
2518 }
2519 }
2520
2521 return fSuccess;
2522}
2523
2524/**
2525 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2526 * @pAdapter: pointer to adapter
2527 * @staId: station id
2528 *
2529 * Return:
2530 * true if we remove MAX_IBSS_PEERS or less STA
2531 * false otherwise.
2532 */
2533static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2534{
2535 bool fSuccess = false;
2536 int idx = 0;
2537 uint8_t valid_idx = 0;
2538 uint8_t del_idx = 0;
2539 uint8_t empty_slots = 0;
2540 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2541
2542 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2543 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2544 pHddStaCtx->conn_info.staId[idx] = 0;
2545
2546 cdf_zero_macaddr(&pHddStaCtx->conn_info.
2547 peerMacAddress[idx]);
2548
2549 fSuccess = true;
2550
2551 /*
2552 * Note the deleted Index, if its 0 we need special
2553 * handling.
2554 */
2555 del_idx = idx;
2556
2557 empty_slots++;
2558 } else {
2559 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2560 valid_idx = idx;
2561 } else {
2562 /* Found an empty slot */
2563 empty_slots++;
2564 }
2565 }
2566 }
2567
2568 if (MAX_IBSS_PEERS == empty_slots) {
2569 /* Last peer departed, set the IBSS state appropriately */
2570 pHddStaCtx->conn_info.connState =
2571 eConnectionState_IbssDisconnected;
2572 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2573 }
2574 /* Find next active staId, to have a valid sta trigger for TL. */
2575 if (fSuccess == true) {
2576 if (del_idx == 0) {
2577 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2578 pHddStaCtx->conn_info.staId[0] =
2579 pHddStaCtx->conn_info.staId[valid_idx];
2580 cdf_copy_macaddr(&pHddStaCtx->conn_info.
2581 peerMacAddress[0],
2582 &pHddStaCtx->conn_info.
2583 peerMacAddress[valid_idx]);
2584
2585 pHddStaCtx->conn_info.staId[valid_idx] = 0;
2586 cdf_zero_macaddr(&pHddStaCtx->conn_info.
2587 peerMacAddress[valid_idx]);
2588 }
2589 }
2590 }
2591 return fSuccess;
2592}
2593
2594/**
2595 * roam_ibss_connect_handler() - IBSS connection handler
2596 * @pAdapter: pointer to adapter
2597 * @pRoamInfo: pointer to roam info
2598 *
2599 * We update the status of the IBSS to connected in this function.
2600 *
2601 * Return: CDF_STATUS enumeration
2602 */
2603static CDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
2604 tCsrRoamInfo *pRoamInfo)
2605{
2606 struct cfg80211_bss *bss;
2607 hddLog(LOG1, FL("IBSS Connect Indication from SME. Set HDD connState to eConnectionState_IbssConnected"));
2608 /*
2609 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2610 * a partner stations).
2611 */
2612 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2613
2614 /* Save the connection info from CSR... */
2615 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2616
2617 /* Send the bssid address to the wext. */
2618 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2619 /* add bss_id to cfg80211 data base */
2620 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2621 if (NULL == bss) {
2622 hddLog(LOGE,
2623 FL("%s: unable to create IBSS entry"),
2624 pAdapter->dev->name);
2625 return CDF_STATUS_E_FAILURE;
2626 }
2627 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002628 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002629 bss);
2630
2631 return CDF_STATUS_SUCCESS;
2632}
2633
2634/**
2635 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2636 * @pAdapter: pointer to adapter
2637 * @pRoamInfo: pointer to roam info
2638 * @roamId: roam id
2639 * @roamStatus: roam status
2640 * @roamResult: roam result
2641 *
2642 * This function indicates the Mic failure to the supplicant
2643 *
2644 * Return: CDF_STATUS enumeration
2645 */
2646static CDF_STATUS
2647hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2648 tCsrRoamInfo *pRoamInfo,
2649 uint32_t roamId,
2650 eRoamCmdStatus roamStatus,
2651 eCsrRoamResult roamResult)
2652{
2653 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2654
2655 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2656 TKIP_COUNTER_MEASURE_STOPED ==
2657 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2658 struct iw_michaelmicfailure msg;
2659 union iwreq_data wreq;
2660 memset(&msg, '\0', sizeof(msg));
2661 msg.src_addr.sa_family = ARPHRD_ETHER;
2662 memcpy(msg.src_addr.sa_data,
2663 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2664 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2665 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2666 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2667
2668 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2669 msg.flags = IW_MICFAILURE_GROUP;
2670 else
2671 msg.flags = IW_MICFAILURE_PAIRWISE;
2672 memset(&wreq, 0, sizeof(wreq));
2673 wreq.data.length = sizeof(msg);
2674 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2675 (char *)&msg);
2676 /* inform mic failure to nl80211 */
2677 cfg80211_michael_mic_failure(pAdapter->dev,
2678 pRoamInfo->u.pMICFailureInfo->
2679 taMacAddr,
2680 ((pRoamInfo->u.pMICFailureInfo->
2681 multicast ==
2682 eSIR_TRUE) ?
2683 NL80211_KEYTYPE_GROUP :
2684 NL80211_KEYTYPE_PAIRWISE),
2685 pRoamInfo->u.pMICFailureInfo->
2686 keyId,
2687 pRoamInfo->u.pMICFailureInfo->TSC,
2688 GFP_KERNEL);
2689
2690 }
2691
2692 return CDF_STATUS_SUCCESS;
2693}
2694
2695/**
2696 * roam_roam_connect_status_update_handler() - IBSS connect status update
2697 * @pAdapter: pointer to adapter
2698 * @pRoamInfo: pointer to roam info
2699 * @roamId: roam id
2700 * @roamStatus: roam status
2701 * @roamResult: roam result
2702 *
2703 * The Ibss connection status is updated regularly here in this function.
2704 *
2705 * Return: CDF_STATUS enumeration
2706 */
2707static CDF_STATUS
2708roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2709 tCsrRoamInfo *pRoamInfo,
2710 uint32_t roamId,
2711 eRoamCmdStatus roamStatus,
2712 eCsrRoamResult roamResult)
2713{
2714 CDF_STATUS cdf_status;
2715
2716 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2717 switch (roamResult) {
2718 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2719 {
2720 hdd_station_ctx_t *pHddStaCtx =
2721 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2722 struct station_info staInfo;
2723
2724 pr_info("IBSS New Peer indication from SME "
2725 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2726 MAC_ADDRESS_STR " and stationID= %d",
2727 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2728 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2729 pRoamInfo->staId);
2730
2731 if (!roam_save_ibss_station
2732 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2733 pRoamInfo->staId,
2734 &pRoamInfo->peerMac)) {
2735 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2736 break;
2737 }
2738
2739 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2740
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002741 /* Register the Station with TL for the new peer. */
2742 cdf_status = hdd_roam_register_sta(pAdapter,
2743 pRoamInfo,
2744 pRoamInfo->staId,
2745 &pRoamInfo->peerMac,
2746 pRoamInfo->pBssDesc);
2747 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2748 hddLog(LOGE,
2749 "Cannot register STA with TL for IBSS. Failed with cdf_status = %d [%08X]",
2750 cdf_status, cdf_status);
2751 }
2752 pHddStaCtx->ibss_sta_generation++;
2753 memset(&staInfo, 0, sizeof(staInfo));
2754 staInfo.filled = 0;
2755 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2756
2757 cfg80211_new_sta(pAdapter->dev,
2758 (const u8 *)pRoamInfo->peerMac.bytes,
2759 &staInfo, GFP_KERNEL);
2760
2761 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2762 pHddStaCtx->ibss_enc_key.encType
2763 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2764 pHddStaCtx->ibss_enc_key.encType
2765 || eCSR_ENCRYPT_TYPE_TKIP ==
2766 pHddStaCtx->ibss_enc_key.encType
2767 || eCSR_ENCRYPT_TYPE_AES ==
2768 pHddStaCtx->ibss_enc_key.encType) {
2769 pHddStaCtx->ibss_enc_key.keyDirection =
2770 eSIR_TX_RX;
2771 cdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
2772 &pRoamInfo->peerMac);
2773
2774 hddLog(LOG2, "New peer joined set PTK encType=%d",
2775 pHddStaCtx->ibss_enc_key.encType);
2776
2777 cdf_status =
2778 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2779 (pAdapter),
2780 pAdapter->sessionId,
2781 &pHddStaCtx->ibss_enc_key,
2782 &roamId);
2783
2784 if (CDF_STATUS_SUCCESS != cdf_status) {
2785 hddLog(LOGE,
2786 FL("sme_roam_set_key failed, status=%d"),
2787 cdf_status);
2788 return CDF_STATUS_E_FAILURE;
2789 }
2790 }
2791 hddLog(LOG1, FL("Enabling queues"));
2792 wlan_hdd_netif_queue_control(pAdapter,
2793 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2794 WLAN_CONTROL_PATH);
2795 break;
2796 }
2797
2798 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2799 {
2800
2801 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2802
2803 break;
2804 }
2805 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2806 {
2807 hdd_station_ctx_t *pHddStaCtx =
2808 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2809
2810 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2811 hddLog(LOGW,
2812 "IBSS peer departed by cannot find peer in our registration table with TL");
2813
2814 pr_info("IBSS Peer Departed from SME "
2815 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2816 MAC_ADDRESS_STR " and stationID= %d",
2817 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2818 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2819 pRoamInfo->staId);
2820
2821 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2822
2823 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2824 pHddStaCtx->ibss_sta_generation++;
2825
2826 cfg80211_del_sta(pAdapter->dev,
2827 (const u8 *)&pRoamInfo->peerMac.bytes,
2828 GFP_KERNEL);
2829 break;
2830 }
2831 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2832 {
2833 hddLog(LOG3,
2834 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2835 /* Stop only when we are inactive */
2836 hddLog(LOG1, FL("Disabling queues"));
2837 wlan_hdd_netif_queue_control(pAdapter,
2838 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2839 WLAN_CONTROL_PATH);
2840 hddLog(LOG1,
2841 FL("Set HDD connState to eConnectionState_NotConnected"));
2842 hdd_conn_set_connection_state(pAdapter,
2843 eConnectionState_NotConnected);
2844
2845 /* Send the bssid address to the wext. */
2846 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2847 break;
2848 }
2849 default:
2850 break;
2851
2852 }
2853
2854 return CDF_STATUS_SUCCESS;
2855}
2856
2857#ifdef FEATURE_WLAN_TDLS
2858/**
2859 * hdd_roam_register_tdlssta() - register new TDLS station
2860 * @pAdapter: pointer to adapter
2861 * @peerMac: pointer to peer MAC address
2862 * @staId: station identifier
2863 * @ucastSig: unicast signature
2864 *
2865 * Construct the staDesc and register with TL the new STA.
2866 * This is called as part of ADD_STA in the TDLS setup.
2867 *
2868 * Return: CDF_STATUS enumeration
2869 */
2870CDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
2871 const uint8_t *peerMac, uint16_t staId,
2872 uint8_t ucastSig)
2873{
2874 CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
2875 struct ol_txrx_desc_type staDesc = { 0 };
2876
2877 /*
2878 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2879 * be peer MAC, here we are working on direct Link
2880 */
2881 staDesc.sta_id = staId;
2882
2883 /* set the QoS field appropriately .. */
2884 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2885 : (staDesc.is_qos_enabled = 0);
2886
2887
2888 /* Register the Station with TL... */
2889 cdf_status = ol_txrx_register_peer(hdd_rx_packet_cbk,
2890 &staDesc);
2891 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2892 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
2893 cdf_status, cdf_status);
2894 return cdf_status;
2895 }
2896
2897 return cdf_status;
2898}
2899
2900/**
2901 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2902 * @pAdapter: pointer to adapter
2903 * @staId: station identifier
2904 *
2905 * Return: CDF_STATUS enumeration
2906 */
2907static CDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
2908 uint8_t staId)
2909{
2910 CDF_STATUS cdf_status;
2911 cdf_status = ol_txrx_clear_peer(staId);
2912 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2913 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
2914 staId, cdf_status, cdf_status);
2915 }
2916 return cdf_status;
2917}
2918
2919/**
2920 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2921 * @pAdapter: pointer to adapter
2922 * @pRoamInfo: pointer to roam info
2923 * @roamId: roam id
2924 * @roamStatus: roam status
2925 * @roamResult: roam result
2926 *
2927 * HDD interface between SME and TL to ensure TDLS client registration with
2928 * TL in case of new TDLS client is added and deregistration at the time
2929 * TDLS client is deleted.
2930 *
2931 * Return: CDF_STATUS enumeration
2932 */
2933static CDF_STATUS
2934hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
2935 tCsrRoamInfo *pRoamInfo,
2936 uint32_t roamId,
2937 eRoamCmdStatus roamStatus,
2938 eCsrRoamResult roamResult)
2939{
2940 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2941 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2942 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
2943 CDF_STATUS status = CDF_STATUS_E_FAILURE;
2944 uint8_t staIdx;
2945 hddTdlsPeer_t *curr_peer;
2946 uint32_t reason;
2947
2948 hddLog(LOG2,
2949 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
2950 roamResult ==
2951 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
2952 ==
2953 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
2954 roamResult ==
2955 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
2956 : roamResult ==
2957 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
2958 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
2959 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
2960 roamResult ==
2961 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
2962 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
2963 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
2964 : roamResult ==
2965 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
2966 : roamResult ==
2967 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
2968 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
2969 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
2970
2971 if (!pHddTdlsCtx) {
2972 hddLog(LOG1,
2973 FL("TDLS ctx is null, ignore roamResult (%d)"),
2974 roamResult);
2975 return status;
2976 }
2977
2978 switch (roamResult) {
2979 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
2980 {
2981 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
2982 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
2983 pRoamInfo->statusCode);
2984 } else {
2985 /*
2986 * Check if there is available index for this new TDLS
2987 * STA.
2988 */
2989 for (staIdx = 0;
2990 staIdx < pHddCtx->max_num_tdls_sta;
2991 staIdx++) {
2992 if (0 ==
2993 pHddCtx->tdlsConnInfo[staIdx].
2994 staId) {
2995 pHddCtx->tdlsConnInfo[staIdx].
2996 sessionId =
2997 pRoamInfo->sessionId;
2998 pHddCtx->tdlsConnInfo[staIdx].
2999 staId = pRoamInfo->staId;
3000
3001 hddLog(LOGW,
3002 ("TDLS: STA IDX at %d is %d "
3003 "of mac "
3004 MAC_ADDRESS_STR),
3005 staIdx,
3006 pHddCtx->
3007 tdlsConnInfo[staIdx].
3008 staId,
3009 MAC_ADDR_ARRAY
3010 (pRoamInfo->peerMac.bytes));
3011
3012 cdf_copy_macaddr(&pHddCtx->
3013 tdlsConnInfo
3014 [staIdx].
3015 peerMac,
3016 &pRoamInfo->
3017 peerMac);
3018 status = CDF_STATUS_SUCCESS;
3019 break;
3020 }
3021 }
3022 if (staIdx < pHddCtx->max_num_tdls_sta) {
3023 if (-1 ==
3024 wlan_hdd_tdls_set_sta_id(pAdapter,
3025 pRoamInfo->
3026 peerMac.bytes,
3027 pRoamInfo->
3028 staId)) {
3029 hddLog(LOGE,
3030 "wlan_hdd_tdls_set_sta_id() failed");
3031 return CDF_STATUS_E_FAILURE;
3032 }
3033
3034 (WLAN_HDD_GET_CTX(pAdapter))->
3035 sta_to_adapter[pRoamInfo->staId] =
3036 pAdapter;
3037 /*
3038 * store the ucast signature,
3039 * if required for further reference.
3040 */
3041
3042 wlan_hdd_tdls_set_signature(pAdapter,
3043 pRoamInfo->
3044 peerMac.bytes,
3045 pRoamInfo->
3046 ucastSig);
3047 } else {
3048 status = CDF_STATUS_E_FAILURE;
3049 hddLog(LOGE,
3050 FL("no available slot in conn_info. staId %d cannot be stored"),
3051 pRoamInfo->staId);
3052 }
3053 pAdapter->tdlsAddStaStatus = status;
3054 }
3055 complete(&pAdapter->tdls_add_station_comp);
3056 break;
3057 }
3058 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3059 {
3060 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3061 hddLog(LOGE,
3062 FL("Add Sta failed. status code(=%d)"),
3063 pRoamInfo->statusCode);
3064 }
3065 /* store the ucast signature which will be used later when
3066 * registering to TL
3067 */
3068 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3069 complete(&pAdapter->tdls_add_station_comp);
3070 break;
3071 }
3072 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3073 {
3074 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3075 hddLog(LOGE,
3076 FL("Link Establish Request failed. status(=%d)"),
3077 pRoamInfo->statusCode);
3078 }
3079 complete(&pAdapter->tdls_link_establish_req_comp);
3080 break;
3081 }
3082 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3083 {
3084 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3085 staIdx++) {
3086 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3087 pRoamInfo->sessionId)
3088 && pRoamInfo->staId ==
3089 pHddCtx->tdlsConnInfo[staIdx].staId) {
3090 hddLog(LOGW,
3091 ("HDD: del STA IDX = %x"),
3092 pRoamInfo->staId);
3093
3094 curr_peer =
3095 wlan_hdd_tdls_find_peer(pAdapter,
3096 pRoamInfo->
3097 peerMac.bytes,
3098 true);
3099 if (NULL != curr_peer
3100 && TDLS_IS_CONNECTED(curr_peer)) {
3101 hdd_roam_deregister_tdlssta
3102 (pAdapter,
3103 pRoamInfo->staId);
3104 wlan_hdd_tdls_decrement_peer_count
3105 (pAdapter);
3106 }
3107 wlan_hdd_tdls_reset_peer(pAdapter,
3108 pRoamInfo->
3109 peerMac.bytes);
3110
3111 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3112 pHddCtx->tdlsConnInfo[staIdx].
3113 sessionId = 255;
3114 cdf_mem_zero(&pHddCtx->
3115 tdlsConnInfo[staIdx].
3116 peerMac,
3117 CDF_MAC_ADDR_SIZE);
3118 status = CDF_STATUS_SUCCESS;
3119 break;
3120 }
3121 }
3122 complete(&pAdapter->tdls_del_station_comp);
3123 }
3124 break;
3125 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3126 {
3127 hddLog(LOGE,
3128 FL("Sending teardown to supplicant with reason code %u"),
3129 pRoamInfo->reasonCode);
3130
3131 curr_peer =
3132 wlan_hdd_tdls_find_peer(pAdapter,
3133 pRoamInfo->peerMac.bytes, true);
3134 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3135 pRoamInfo->reasonCode);
3136 status = CDF_STATUS_SUCCESS;
3137 break;
3138 }
3139 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3140 {
3141 /* 0 staIdx is assigned to AP we dont want to touch that */
3142 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3143 staIdx++) {
3144 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3145 pRoamInfo->sessionId)
3146 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3147 hddLog(LOGW,
3148 ("hdd_tdlsStatusUpdate: staIdx %d "
3149 MAC_ADDRESS_STR),
3150 pHddCtx->tdlsConnInfo[staIdx].
3151 staId,
3152 MAC_ADDR_ARRAY(pHddCtx->
3153 tdlsConnInfo
3154 [staIdx].
3155 peerMac.
3156 bytes));
3157 wlan_hdd_tdls_reset_peer(pAdapter,
3158 pHddCtx->
3159 tdlsConnInfo
3160 [staIdx].
3161 peerMac.bytes);
3162 hdd_roam_deregister_tdlssta(pAdapter,
3163 pHddCtx->
3164 tdlsConnInfo
3165 [staIdx].
3166 staId);
3167 cdf_mem_zero(&smeTdlsPeerStateParams,
3168 sizeof
3169 (smeTdlsPeerStateParams));
3170 smeTdlsPeerStateParams.vdevId =
3171 pHddCtx->tdlsConnInfo[staIdx].
3172 sessionId;
3173 cdf_mem_copy(&smeTdlsPeerStateParams.
3174 peerMacAddr,
3175 &pHddCtx->
3176 tdlsConnInfo[staIdx].
3177 peerMac.bytes,
3178 CDF_MAC_ADDR_SIZE);
3179 smeTdlsPeerStateParams.peerState =
3180 eSME_TDLS_PEER_STATE_TEARDOWN;
3181
3182 hddLog(LOG1,
3183 FL("calling sme_update_tdls_peer_state for staIdx %d "
3184 MAC_ADDRESS_STR),
3185 pHddCtx->tdlsConnInfo[staIdx].
3186 staId,
3187 MAC_ADDR_ARRAY(pHddCtx->
3188 tdlsConnInfo
3189 [staIdx].
3190 peerMac.
3191 bytes));
3192 status =
3193 sme_update_tdls_peer_state(
3194 pHddCtx->hHal,
3195 &smeTdlsPeerStateParams);
3196 if (CDF_STATUS_SUCCESS != status) {
3197 hddLog(LOGE,
3198 FL("sme_update_tdls_peer_state failed for "
3199 MAC_ADDRESS_STR),
3200 MAC_ADDR_ARRAY
3201 (pHddCtx->
3202 tdlsConnInfo[staIdx].
3203 peerMac.bytes));
3204 }
3205 wlan_hdd_tdls_decrement_peer_count
3206 (pAdapter);
3207
3208 cdf_mem_zero(&pHddCtx->
3209 tdlsConnInfo[staIdx].
3210 peerMac,
3211 CDF_MAC_ADDR_SIZE);
3212 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3213 pHddCtx->tdlsConnInfo[staIdx].
3214 sessionId = 255;
3215
3216 status = CDF_STATUS_SUCCESS;
3217 }
3218 }
3219 break;
3220 }
3221 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3222 {
3223 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
3224 if (((1 << CDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3225 (pHddCtx->no_of_active_sessions[CDF_STA_MODE] > 1)) {
3226 hddLog(LOG2,
3227 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3228 pHddCtx->concurrency_mode,
3229 pHddCtx->no_of_active_sessions[CDF_STA_MODE]);
3230 status = CDF_STATUS_E_FAILURE;
3231 break;
3232 }
3233
3234 curr_peer =
3235 wlan_hdd_tdls_get_peer(pAdapter,
3236 pRoamInfo->peerMac.bytes);
3237 if (!curr_peer) {
3238 hddLog(LOGE, FL("curr_peer is null"));
3239 status = CDF_STATUS_E_FAILURE;
3240 } else {
3241 if (eTDLS_LINK_CONNECTED ==
3242 curr_peer->link_status) {
3243 hddLog(LOGE,
3244 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3245 } else {
3246 /*
3247 * If external control is enabled then initiate
3248 * TDLS only if forced peer is set otherwise
3249 * ignore should Discover trigger from fw.
3250 */
3251 if (pHddCtx->config->
3252 fTDLSExternalControl
3253 && (false ==
3254 curr_peer->isForcedPeer)) {
3255 hddLog(LOG2,
3256 FL
3257 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
3258 status = CDF_STATUS_SUCCESS;
3259 break;
3260 } else {
3261 hddLog(LOG2,
3262 FL
3263 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3264 pHddCtx->config->
3265 fTDLSExternalControl,
3266 curr_peer->isForcedPeer,
3267 pRoamInfo->reasonCode);
3268 }
3269 wlan_hdd_tdls_pre_setup_init_work
3270 (pHddTdlsCtx, curr_peer);
3271 }
3272 status = CDF_STATUS_SUCCESS;
3273 }
3274 break;
3275 }
3276
3277 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3278 {
3279 curr_peer =
3280 wlan_hdd_tdls_find_peer(pAdapter,
3281 pRoamInfo->peerMac.bytes, true);
3282 if (!curr_peer) {
3283 hddLog(LOGE, FL("curr_peer is null"));
3284 status = CDF_STATUS_E_FAILURE;
3285 } else {
3286 if (eTDLS_LINK_CONNECTED ==
3287 curr_peer->link_status) {
3288 hddLog(LOGE,
3289 FL
3290 ("Received SHOULD_TEARDOWN for peer "
3291 MAC_ADDRESS_STR
3292 " staId: %d, reason: %d"),
3293 MAC_ADDR_ARRAY(pRoamInfo->
3294 peerMac.bytes),
3295 pRoamInfo->staId,
3296 pRoamInfo->reasonCode);
3297
3298 if (pRoamInfo->reasonCode ==
3299 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3300 pRoamInfo->reasonCode ==
3301 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3302 pRoamInfo->reasonCode ==
3303 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3304 pRoamInfo->reasonCode ==
3305 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3306 reason =
3307 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3308 } else
3309 reason =
3310 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3311
3312 wlan_hdd_tdls_indicate_teardown
3313 (pHddTdlsCtx->pAdapter, curr_peer,
3314 reason);
3315 } else {
3316 hddLog(LOGE,
3317 FL
3318 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3319 pRoamInfo->reasonCode);
3320 }
3321 status = CDF_STATUS_SUCCESS;
3322 }
3323 break;
3324 }
3325
3326 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3327 {
3328 curr_peer =
3329 wlan_hdd_tdls_find_peer(pAdapter,
3330 pRoamInfo->peerMac.bytes, true);
3331 if (!curr_peer) {
3332 hddLog(LOGE, FL("curr_peer is null"));
3333 status = CDF_STATUS_E_FAILURE;
3334 } else {
3335 if (eTDLS_LINK_CONNECTED ==
3336 curr_peer->link_status) {
3337 hddLog(LOGE,
3338 FL
3339 ("Received SHOULD_PEER_DISCONNECTED for peer "
3340 MAC_ADDRESS_STR
3341 " staId: %d, reason: %d"),
3342 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3343 pRoamInfo->staId,
3344 pRoamInfo->reasonCode);
3345
3346 if (pRoamInfo->reasonCode ==
3347 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3348 pRoamInfo->reasonCode ==
3349 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3350 pRoamInfo->reasonCode ==
3351 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3352 pRoamInfo->reasonCode ==
3353 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3354 reason =
3355 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3356 } else
3357 reason =
3358 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3359
3360 wlan_hdd_tdls_indicate_teardown
3361 (pHddTdlsCtx->pAdapter, curr_peer,
3362 reason);
3363 } else {
3364 hddLog(LOGE,
3365 FL
3366 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3367 pRoamInfo->reasonCode);
3368 }
3369 status = CDF_STATUS_SUCCESS;
3370 }
3371 break;
3372 }
3373 default:
3374 {
3375 break;
3376 }
3377 }
3378
3379 return status;
3380}
3381#endif
3382
3383#ifdef WLAN_FEATURE_11W
3384/**
3385 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3386 * @pAdapter: pointer to the adapter
3387 * @nFrameLength: Length of the unprotected frame being passed
3388 * @pbFrames: Pointer to the frame buffer
3389 * @frameType: 802.11 frame type
3390 *
3391 * This function forwards the unprotected management frame to the supplicant.
3392 *
3393 * Return: nothing
3394 */
3395static void
3396hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3397 uint8_t *pbFrames, uint8_t frameType)
3398{
3399 uint8_t type = 0;
3400 uint8_t subType = 0;
3401
3402 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3403 frameType, nFrameLength);
3404
3405 /* Sanity Checks */
3406 if (NULL == pAdapter) {
3407 hddLog(LOGE, FL("pAdapter is NULL"));
3408 return;
3409 }
3410
3411 if (NULL == pAdapter->dev) {
3412 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3413 return;
3414 }
3415
3416 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3417 hddLog(LOGE, FL("pAdapter has invalid magic"));
3418 return;
3419 }
3420
3421 if (!nFrameLength) {
3422 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3423 return;
3424 }
3425
3426 if (NULL == pbFrames) {
3427 hddLog(LOGE, FL("pbFrames is NULL"));
3428 return;
3429 }
3430
3431 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3432 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3433
3434 /* Get pAdapter from Destination mac address of the frame */
3435 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3436#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3437 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3438 nFrameLength);
3439#else
3440 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3441 nFrameLength);
3442#endif
3443 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3444 } else if (type == SIR_MAC_MGMT_FRAME &&
3445 subType == SIR_MAC_MGMT_DEAUTH) {
3446#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3447 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3448 nFrameLength);
3449#else
3450 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3451 nFrameLength);
3452#endif
3453 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3454 } else {
3455 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3456 type, subType);
3457 return;
3458 }
3459}
3460#endif
3461
3462#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
3463/**
3464 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3465 * @pAdapter: pointer to adapter
3466 * @tid: traffic identifier
3467 * @state: state
3468 * @measInterval: measurement interval
3469 *
3470 * This function sends traffic stream metrics IE information to
3471 * the supplicant via wireless event.
3472 *
3473 * Return: none
3474 */
3475static void
3476hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3477 uint8_t state, uint16_t measInterval)
3478{
3479 union iwreq_data wrqu;
3480 char buf[IW_CUSTOM_MAX + 1];
3481 int nBytes = 0;
3482
3483 if (NULL == pAdapter)
3484 return;
3485
3486 /* create the event */
3487 memset(&wrqu, '\0', sizeof(wrqu));
3488 memset(buf, '\0', sizeof(buf));
3489
3490 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3491 tid, state, measInterval);
3492
3493 nBytes =
3494 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3495 measInterval);
3496
3497 wrqu.data.pointer = buf;
3498 wrqu.data.length = nBytes;
3499 /* send the event */
3500 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3501}
3502
3503/**
3504 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3505 * @pAdapter: pointer to adapter
3506 * @pRoamInfo: pointer to roam info
3507 *
3508 * This function sends cckm preauth indication to the supplicant
3509 * via wireless custom event.
3510 *
3511 * Return: none
3512 */
3513static void
3514hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3515{
3516 union iwreq_data wrqu;
3517 char buf[IW_CUSTOM_MAX + 1];
3518 char *pos = buf;
3519 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3520
3521 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3522 return;
3523
3524 /* create the event */
3525 memset(&wrqu, '\0', sizeof(wrqu));
3526 memset(buf, '\0', sizeof(buf));
3527
3528 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3529 hddLog(LOG1,
3530 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3531 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3532 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3533
3534 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3535 pos += nBytes;
3536 freeBytes -= nBytes;
3537
3538 cdf_mem_copy(pos, pRoamInfo->bssid.bytes, CDF_MAC_ADDR_SIZE);
3539 pos += CDF_MAC_ADDR_SIZE;
3540 freeBytes -= CDF_MAC_ADDR_SIZE;
3541
3542 nBytes = snprintf(pos, freeBytes, " %u:%u",
3543 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3544 freeBytes -= nBytes;
3545
3546 wrqu.data.pointer = buf;
3547 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3548
3549 /* send the event */
3550 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3551}
3552
3553/**
3554 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3555 * @pAdapter: pointer to adapter
3556 * @pRoamInfo: pointer to roam info
3557 *
3558 * Return: none
3559 */
3560static void
3561hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3562 tCsrRoamInfo *pRoamInfo)
3563{
3564 union iwreq_data wrqu;
3565 char buf[IW_CUSTOM_MAX + 1];
3566 int nBytes = 0;
3567
3568 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3569 return;
3570
3571 /* create the event */
3572 memset(&wrqu, '\0', sizeof(wrqu));
3573 memset(buf, '\0', sizeof(buf));
3574
3575 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3576
3577 nBytes =
3578 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3579 pRoamInfo->tsmRoamDelay);
3580
3581 wrqu.data.pointer = buf;
3582 wrqu.data.length = nBytes;
3583
3584 /* send the event */
3585 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3586}
3587
3588/**
3589 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3590 * @pAdapter: pointer to adapter
3591 * @measurementToken: measurement token
3592 * @flag: flag
3593 * @numBss: number of bss
3594 *
3595 * If the measurement is none and no scan results found,
3596 * indicate the supplicant about measurement done.
3597 *
3598 * Return: none
3599 */
3600void
3601hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3602 const uint16_t measurementToken,
3603 const bool flag, const uint8_t numBss)
3604{
3605 union iwreq_data wrqu;
3606 char buf[IW_CUSTOM_MAX];
3607 char *pos = buf;
3608 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3609
3610 memset(&wrqu, '\0', sizeof(wrqu));
3611 memset(buf, '\0', sizeof(buf));
3612
3613 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3614 flag, numBss);
3615
3616 nBytes =
3617 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3618 flag, numBss);
3619
3620 wrqu.data.pointer = buf;
3621 wrqu.data.length = nBytes;
3622 /* send the event */
3623 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3624}
3625
3626/**
3627 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3628 * @pAdapter: pointer to adapter
3629 * @pRoamInfo: pointer to roam info
3630 *
3631 * If the measurement is none and no scan results found,
3632 * indicate the supplicant about measurement done.
3633 *
3634 * Return: none
3635 */
3636static void
3637hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3638 const tCsrRoamInfo *pRoamInfo)
3639{
3640 union iwreq_data wrqu;
3641 char buf[IW_CUSTOM_MAX];
3642 char *pos = buf;
3643 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3644 uint8_t i = 0, len = 0;
3645 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3646 uint8_t lastSent = 0, sendBss = 0;
3647 int bcnRepFieldSize =
3648 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3649 bcnReportFields);
3650 uint8_t ieLenByte = 1;
3651 /*
3652 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3653 */
3654#define ESEBCNREPHEADER_LEN (18)
3655
3656 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3657 return;
3658
3659 /*
3660 * Custom event can pass maximum of 256 bytes of data,
3661 * based on the IE len we need to identify how many BSS info can
3662 * be filled in to custom event data.
3663 */
3664 /*
3665 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3666 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3667 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3668 */
3669
3670 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3671 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3672 hddLog(LOG1,
3673 "Measurement Done but no scan results");
3674 /* If the measurement is none and no scan results found,
3675 indicate the supplicant about measurement done */
3676 hdd_indicate_ese_bcn_report_no_results(
3677 pAdapter,
3678 pRoamInfo->pEseBcnReportRsp->
3679 measurementToken,
3680 pRoamInfo->pEseBcnReportRsp->flag,
3681 pRoamInfo->pEseBcnReportRsp->numBss);
3682 } else {
3683 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3684 memset(&wrqu, '\0', sizeof(wrqu));
3685 memset(buf, '\0', sizeof(buf));
3686 tot_bcn_ieLen = 0;
3687 sendBss = 0;
3688 pos = buf;
3689 freeBytes = IW_CUSTOM_MAX;
3690
3691 for (i = lastSent;
3692 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3693 len =
3694 bcnRepFieldSize + ieLenByte +
3695 pRoamInfo->pEseBcnReportRsp->
3696 bcnRepBssInfo[i].ieLen;
3697 if ((len + tot_bcn_ieLen) >
3698 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3699 break;
3700 }
3701 tot_bcn_ieLen += len;
3702 sendBss++;
3703 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3704 i, bcnRepFieldSize, 1,
3705 pRoamInfo->pEseBcnReportRsp->
3706 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3707 }
3708
3709 hddLog(LOG1, "Sending %d BSS Info",
3710 sendBss);
3711 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3712 pRoamInfo->pEseBcnReportRsp->measurementToken,
3713 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3714 tot_bcn_ieLen);
3715
3716 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3717 pRoamInfo->pEseBcnReportRsp->
3718 measurementToken,
3719 pRoamInfo->pEseBcnReportRsp->flag,
3720 sendBss);
3721 pos += nBytes;
3722 freeBytes -= nBytes;
3723
3724 /* Copy total Beacon report data length */
3725 cdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
3726 sizeof(tot_bcn_ieLen));
3727 pos += sizeof(tot_bcn_ieLen);
3728 freeBytes -= sizeof(tot_bcn_ieLen);
3729
3730 for (i = 0; i < sendBss; i++) {
3731 hddLog(LOG1,
3732 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3733 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3734 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3735 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3736 pRoamInfo->pEseBcnReportRsp->
3737 bcnRepBssInfo[i +
3738 lastSent].bcnReportFields.
3739 ChanNum,
3740 pRoamInfo->pEseBcnReportRsp->
3741 bcnRepBssInfo[i +
3742 lastSent].bcnReportFields.
3743 Spare,
3744 pRoamInfo->pEseBcnReportRsp->
3745 bcnRepBssInfo[i +
3746 lastSent].bcnReportFields.
3747 MeasDuration,
3748 pRoamInfo->pEseBcnReportRsp->
3749 bcnRepBssInfo[i +
3750 lastSent].bcnReportFields.
3751 PhyType,
3752 pRoamInfo->pEseBcnReportRsp->
3753 bcnRepBssInfo[i +
3754 lastSent].bcnReportFields.
3755 RecvSigPower,
3756 pRoamInfo->pEseBcnReportRsp->
3757 bcnRepBssInfo[i +
3758 lastSent].bcnReportFields.
3759 ParentTsf,
3760 pRoamInfo->pEseBcnReportRsp->
3761 bcnRepBssInfo[i +
3762 lastSent].bcnReportFields.
3763 TargetTsf[0],
3764 pRoamInfo->pEseBcnReportRsp->
3765 bcnRepBssInfo[i +
3766 lastSent].bcnReportFields.
3767 TargetTsf[1],
3768 pRoamInfo->pEseBcnReportRsp->
3769 bcnRepBssInfo[i +
3770 lastSent].bcnReportFields.
3771 BcnInterval,
3772 pRoamInfo->pEseBcnReportRsp->
3773 bcnRepBssInfo[i +
3774 lastSent].bcnReportFields.
3775 CapabilityInfo,
3776 pRoamInfo->pEseBcnReportRsp->
3777 bcnRepBssInfo[i +
3778 lastSent].bcnReportFields.
3779 Bssid[0],
3780 pRoamInfo->pEseBcnReportRsp->
3781 bcnRepBssInfo[i +
3782 lastSent].bcnReportFields.
3783 Bssid[1],
3784 pRoamInfo->pEseBcnReportRsp->
3785 bcnRepBssInfo[i +
3786 lastSent].bcnReportFields.
3787 Bssid[2],
3788 pRoamInfo->pEseBcnReportRsp->
3789 bcnRepBssInfo[i +
3790 lastSent].bcnReportFields.
3791 Bssid[3],
3792 pRoamInfo->pEseBcnReportRsp->
3793 bcnRepBssInfo[i +
3794 lastSent].bcnReportFields.
3795 Bssid[4],
3796 pRoamInfo->pEseBcnReportRsp->
3797 bcnRepBssInfo[i +
3798 lastSent].bcnReportFields.
3799 Bssid[5]);
3800
3801 /* bcn report fields are copied */
3802 len =
3803 sizeof(pRoamInfo->pEseBcnReportRsp->
3804 bcnRepBssInfo[i +
3805 lastSent].
3806 bcnReportFields);
3807 cdf_mem_copy(pos,
3808 (char *)&pRoamInfo->
3809 pEseBcnReportRsp->bcnRepBssInfo[i +
3810 lastSent].
3811 bcnReportFields, len);
3812 pos += len;
3813 freeBytes -= len;
3814
3815 /* Add 1 byte of ie len */
3816 len =
3817 pRoamInfo->pEseBcnReportRsp->
3818 bcnRepBssInfo[i + lastSent].ieLen;
3819 cdf_mem_copy(pos, (char *)&len, sizeof(len));
3820 pos += sizeof(len);
3821 freeBytes -= sizeof(len);
3822
3823 /* copy IE from scan results */
3824 cdf_mem_copy(pos,
3825 (char *)pRoamInfo->
3826 pEseBcnReportRsp->bcnRepBssInfo[i +
3827 lastSent].
3828 pBuf, len);
3829 pos += len;
3830 freeBytes -= len;
3831 }
3832
3833 wrqu.data.pointer = buf;
3834 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3835
3836 /* send the event */
3837 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3838 buf);
3839 lastSent += sendBss;
3840 }
3841 }
3842}
3843
3844#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
3845
3846/**
3847 * hdd_sme_roam_callback() - hdd sme roam callback
3848 * @pContext: pointer to adapter context
3849 * @pRoamInfo: pointer to roam info
3850 * @roamId: roam id
3851 * @roamStatus: roam status
3852 * @roamResult: roam result
3853 *
3854 * Return: CDF_STATUS enumeration
3855 */
3856CDF_STATUS
3857hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3858 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3859{
3860 CDF_STATUS cdf_ret_status = CDF_STATUS_SUCCESS;
3861 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3862 hdd_wext_state_t *pWextState = NULL;
3863 hdd_station_ctx_t *pHddStaCtx = NULL;
3864 CDF_STATUS status = CDF_STATUS_SUCCESS;
3865 hdd_context_t *pHddCtx = NULL;
3866
3867 hddLog(LOG2,
3868 "CSR Callback: status= %d result= %d roamID=%d",
3869 roamStatus, roamResult, roamId);
3870
3871 /* Sanity check */
3872 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3873 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
3874 return CDF_STATUS_E_FAILURE;
3875 }
3876
3877 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3878 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3879
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05303880 MTRACE(cdf_trace(CDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
3881 pAdapter->sessionId, roamStatus));
3882
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003883 switch (roamStatus) {
3884 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05303885 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3886 complete(&pAdapter->session_open_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003887 break;
3888
3889#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
3890defined(FEATURE_WLAN_LFR)
3891 /*
3892 * We did pre-auth,then we attempted a 11r or ese reassoc.
3893 * reassoc failed due to failure, timeout, reject from ap
3894 * in any case tell the OS, our carrier is off and mark
3895 * interface down.
3896 */
3897 case eCSR_ROAM_FT_REASSOC_FAILED:
3898 hddLog(LOGE,
3899 FL
3900 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
3901 roamStatus, roamResult, pAdapter->sessionId);
3902 cdf_ret_status =
3903 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3904 roamStatus, roamResult);
3905 /*
3906 * Check if Mcast/Bcast Filters are set, if yes
3907 * clear the filters here.
3908 */
3909 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
3910 true) {
3911 (WLAN_HDD_GET_CTX(pAdapter))->
3912 hdd_mcastbcast_filter_set = false;
3913 }
3914 pHddStaCtx->ft_carrier_on = false;
3915 pHddStaCtx->hdd_ReassocScenario = false;
3916 hddLog(LOG1,
3917 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
3918 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3919 break;
3920
3921 case eCSR_ROAM_FT_START:
3922 /*
3923 * When we roam for ESE and 11r, we dont want the OS to be
3924 * informed that the link is down. So mark the link ready for
3925 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
3926 * be received. Where in we will not mark the link down
3927 * Also we want to stop tx at this point when we will be
3928 * doing disassoc at this time. This saves 30-60 msec
3929 * after reassoc.
3930 */
3931 {
3932 hddLog(LOG1, FL("Disabling queues"));
3933 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE,
3934 WLAN_CONTROL_PATH);
3935 status =
3936 hdd_roam_deregister_sta(pAdapter,
3937 pHddStaCtx->conn_info.
3938 staId[0]);
3939 if (!CDF_IS_STATUS_SUCCESS(status)) {
3940 hddLog(LOGW,
3941 FL
3942 ("hdd_roam_deregister_sta() failed to for staID %d. Status=%d [0x%x]"),
3943 pHddStaCtx->conn_info.staId[0],
3944 status, status);
3945 cdf_ret_status = CDF_STATUS_E_FAILURE;
3946 }
3947 }
3948 pHddStaCtx->ft_carrier_on = true;
3949 pHddStaCtx->hdd_ReassocScenario = true;
3950 hddLog(LOG1,
3951 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
3952 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3953 break;
3954#endif
3955
3956 case eCSR_ROAM_SHOULD_ROAM:
3957 /* Dont need to do anything */
3958 {
3959 hdd_station_ctx_t *pHddStaCtx =
3960 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3961 /* notify apps that we can't pass traffic anymore */
3962 hddLog(LOG1, FL("Disabling queues"));
3963 wlan_hdd_netif_queue_control(pAdapter,
3964 WLAN_NETIF_TX_DISABLE,
3965 WLAN_CONTROL_PATH);
3966#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
3967defined(FEATURE_WLAN_LFR)
3968 if (pHddStaCtx->ft_carrier_on == false) {
3969#endif
3970 wlan_hdd_netif_queue_control(pAdapter,
3971 WLAN_NETIF_CARRIER_OFF,
3972 WLAN_CONTROL_PATH);
3973#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
3974defined(FEATURE_WLAN_LFR)
3975 }
3976#endif
3977
3978#if !(defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
3979defined(FEATURE_WLAN_LFR))
3980 /*
3981 * We should clear all sta register with TL, for now, only one.
3982 */
3983 status =
3984 hdd_roam_deregister_sta(pAdapter,
3985 pHddStaCtx->conn_info.
3986 staId[0]);
3987 if (!CDF_IS_STATUS_SUCCESS(status)) {
3988 hddLog(LOGW,
3989 FL
3990 ("hdd_roam_deregister_sta() failed to for staID %d. Status=%d [0x%x]"),
3991 pHddStaCtx->conn_info.staId[0],
3992 status, status);
3993 cdf_ret_status = CDF_STATUS_E_FAILURE;
3994 }
3995#endif
3996 }
3997 break;
3998 case eCSR_ROAM_LOSTLINK:
3999 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
4000 hddLog(LOG2, "Roaming started due to connection lost");
4001 hddLog(LOG1, FL("Disabling queues"));
4002 wlan_hdd_netif_queue_control(pAdapter,
4003 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4004 WLAN_CONTROL_PATH);
4005 break;
4006 }
4007 case eCSR_ROAM_DISASSOCIATED:
4008 {
4009 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
4010 cdf_ret_status =
4011 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4012 roamStatus, roamResult);
4013 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
4014 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4015 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
4016 hdd_conf_mcastbcast_filter(pHddCtx, false);
4017
4018 if (true ==
4019 pHddCtx->sus_res_mcastbcast_filter_valid) {
4020 pHddCtx->configuredMcastBcastFilter =
4021 pHddCtx->sus_res_mcastbcast_filter;
4022 pHddCtx->
4023 sus_res_mcastbcast_filter_valid =
4024 false;
4025 }
4026
4027 hddLog(LOG1,
4028 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4029 hddLog(LOG1,
4030 "McastBcastFilter = %d",
4031 pHddCtx->configuredMcastBcastFilter);
4032 hddLog(LOG1,
4033 "offload: already called mcastbcast filter");
4034 (WLAN_HDD_GET_CTX(pAdapter))->
4035 hdd_mcastbcast_filter_set = false;
4036 }
4037 /* Call to clear any MC Addr List filter applied after
4038 * successful connection.
4039 */
4040 wlan_hdd_set_mc_addr_list(pAdapter, false);
4041 }
4042 break;
4043 case eCSR_ROAM_IBSS_LEAVE:
4044 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
4045 cdf_ret_status =
4046 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4047 roamStatus, roamResult);
4048 break;
4049 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4050 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4051 /*
4052 * To Do - address probable memory leak with WEP encryption upon
4053 * successful association.
4054 */
4055 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4056 /* Clear saved connection information in HDD */
4057 hdd_conn_remove_connect_info(
4058 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4059 }
4060 cdf_ret_status =
4061 hdd_association_completion_handler(pAdapter, pRoamInfo,
4062 roamId, roamStatus,
4063 roamResult);
4064#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4065 if (pRoamInfo)
4066 pRoamInfo->roamSynchInProgress = false;
4067#endif
4068 break;
4069 case eCSR_ROAM_ASSOCIATION_FAILURE:
4070 cdf_ret_status = hdd_association_completion_handler(pAdapter,
4071 pRoamInfo,
4072 roamId,
4073 roamStatus,
4074 roamResult);
4075 break;
4076 case eCSR_ROAM_IBSS_IND:
4077 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4078 roamStatus, roamResult);
4079 break;
4080
4081 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
4082 cdf_ret_status =
4083 roam_roam_connect_status_update_handler(pAdapter,
4084 pRoamInfo,
4085 roamId,
4086 roamStatus,
4087 roamResult);
4088 break;
4089
4090 case eCSR_ROAM_MIC_ERROR_IND:
4091 cdf_ret_status =
4092 hdd_roam_mic_error_indication_handler(pAdapter,
4093 pRoamInfo,
4094 roamId,
4095 roamStatus,
4096 roamResult);
4097 break;
4098
4099 case eCSR_ROAM_SET_KEY_COMPLETE:
4100 {
4101 cdf_ret_status =
4102 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4103 roamId, roamStatus,
4104 roamResult);
4105 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4106 pHddStaCtx->hdd_ReassocScenario = false;
4107 hddLog(LOG1,
4108 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4109 pHddStaCtx->hdd_ReassocScenario,
4110 pAdapter->sessionId);
4111 }
4112 }
4113#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4114 if (pRoamInfo != NULL)
4115 pRoamInfo->roamSynchInProgress = false;
4116#endif
4117 break;
4118#ifdef WLAN_FEATURE_VOWIFI_11R
4119 case eCSR_ROAM_FT_RESPONSE:
4120 hdd_send_ft_event(pAdapter);
4121 break;
4122#endif
Amar Singhal01098f72015-10-08 11:55:32 -07004123#ifdef FEATURE_WLAN_LFR
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004124 case eCSR_ROAM_PMK_NOTIFY:
4125 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType ||
4126 eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
4127 pHddStaCtx->conn_info.authType) {
4128 /* notify the supplicant of a new candidate */
4129 cdf_ret_status =
4130 wlan_hdd_cfg80211_pmksa_candidate_notify(
4131 pAdapter, pRoamInfo, 1, false);
4132 }
4133 break;
4134#endif
4135
4136#ifdef FEATURE_WLAN_LFR_METRICS
4137 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4138 /* This event is to notify pre-auth initiation */
4139 if (CDF_STATUS_SUCCESS !=
4140 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4141 pRoamInfo)) {
4142 cdf_ret_status = CDF_STATUS_E_FAILURE;
4143 }
4144 break;
4145 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4146 /*
4147 * This event will notify pre-auth completion in case of success
4148 */
4149 if (CDF_STATUS_SUCCESS !=
4150 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4151 pRoamInfo, 1)) {
4152 cdf_ret_status = CDF_STATUS_E_FAILURE;
4153 }
4154 break;
4155 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4156 /*
4157 * This event will notify pre-auth completion incase of failure.
4158 */
4159 if (CDF_STATUS_SUCCESS !=
4160 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4161 pRoamInfo, 0)) {
4162 cdf_ret_status = CDF_STATUS_E_FAILURE;
4163 }
4164 break;
4165 case eCSR_ROAM_HANDOVER_SUCCESS:
4166 /* This event is to notify handover success.
4167 It will be only invoked on success */
4168 if (CDF_STATUS_SUCCESS !=
4169 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4170 pRoamInfo)) {
4171 cdf_ret_status = CDF_STATUS_E_FAILURE;
4172 }
4173 break;
4174#endif
4175
4176 case eCSR_ROAM_INDICATE_MGMT_FRAME:
4177 hdd_indicate_mgmt_frame(pAdapter,
4178 pRoamInfo->nFrameLength,
4179 pRoamInfo->pbFrames,
4180 pRoamInfo->frameType,
4181 pRoamInfo->rxChan, pRoamInfo->rxRssi);
4182 break;
4183 case eCSR_ROAM_REMAIN_CHAN_READY:
4184 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4185 break;
4186 case eCSR_ROAM_SEND_ACTION_CNF:
4187 hdd_send_action_cnf(pAdapter,
4188 (roamResult ==
4189 eCSR_ROAM_RESULT_NONE) ? true : false);
4190 break;
4191#ifdef FEATURE_WLAN_TDLS
4192 case eCSR_ROAM_TDLS_STATUS_UPDATE:
4193 cdf_ret_status =
4194 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4195 roamId,
4196 roamStatus,
4197 roamResult);
4198 break;
4199 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4200 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4201 pRoamInfo->reasonCode);
4202 break;
4203#endif
4204#ifdef WLAN_FEATURE_11W
4205 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4206 hdd_indicate_unprot_mgmt_frame(pAdapter,
4207 pRoamInfo->nFrameLength,
4208 pRoamInfo->pbFrames,
4209 pRoamInfo->frameType);
4210 break;
4211#endif
4212#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4213 case eCSR_ROAM_TSM_IE_IND:
4214 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4215 pRoamInfo->tsmIe.state,
4216 pRoamInfo->tsmIe.msmt_interval);
4217 break;
4218
4219 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4220 {
4221 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4222 pHddStaCtx->conn_info.authType
4223 || eCSR_AUTH_TYPE_CCKM_RSN ==
4224 pHddStaCtx->conn_info.authType) {
4225 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4226 }
4227 break;
4228 }
4229
4230 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4231 {
4232 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4233 break;
4234 }
4235
4236 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4237 {
4238 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4239 break;
4240 }
4241#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
4242 default:
4243 break;
4244 }
4245 return cdf_ret_status;
4246}
4247
4248/**
4249 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4250 * @auth_suite: auth suite
4251 *
4252 * Return: eCsrAuthType enumeration
4253 */
4254eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4255{
4256 eCsrAuthType auth_type;
4257 /* is the auth type supported? */
4258 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4259 auth_type = eCSR_AUTH_TYPE_RSN;
4260 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4261 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
4262 } else
4263#ifdef WLAN_FEATURE_VOWIFI_11R
4264 if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
4265 /* Check for 11r FT Authentication with PSK */
4266 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4267 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4268 /* Check for 11R FT Authentication with 802.1X */
4269 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4270 } else
4271#endif
4272#ifdef FEATURE_WLAN_ESE
4273 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4274 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4275 } else
4276#endif /* FEATURE_WLAN_ESE */
4277#ifdef WLAN_FEATURE_11W
4278 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4279 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4280 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4281 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4282 } else
4283#endif
4284 {
4285 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4286 }
4287 return auth_type;
4288}
4289
4290/**
4291 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4292 * @auth_suite: auth suite
4293 *
4294 * Return: eCsrAuthType enumeration
4295 */
4296eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4297{
4298 eCsrAuthType auth_type;
4299 /* is the auth type supported? */
4300 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4301 auth_type = eCSR_AUTH_TYPE_WPA;
4302 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4303 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4304 } else
4305#ifdef FEATURE_WLAN_ESE
4306 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4307 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4308 } else
4309#endif /* FEATURE_WLAN_ESE */
4310 {
4311 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4312 }
4313 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4314 return auth_type;
4315}
4316
4317/**
4318 * hdd_translate_rsn_to_csr_encryption_type() -
4319 * Translate RSN to CSR encryption type
4320 * @cipher_suite: cipher suite
4321 *
4322 * Return: eCsrEncryptionType enumeration
4323 */
4324eCsrEncryptionType
4325hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4326{
4327 eCsrEncryptionType cipher_type;
4328
4329 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4330 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4331 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4332 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4333 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4334 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4335 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4336 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4337 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4338 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4339 else
4340 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4341
4342 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4343 return cipher_type;
4344}
4345
4346/**
4347 * hdd_translate_wpa_to_csr_encryption_type() -
4348 * Translate WPA to CSR encryption type
4349 * @cipher_suite: cipher suite
4350 *
4351 * Return: eCsrEncryptionType enumeration
4352 */
4353eCsrEncryptionType
4354hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4355{
4356 eCsrEncryptionType cipher_type;
4357
4358 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4359 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4360 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4361 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4362 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4363 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4364 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4365 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4366 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4367 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4368 else
4369 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4370
4371 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4372 return cipher_type;
4373}
4374
4375/**
4376 * hdd_process_genie() - process gen ie
4377 * @pAdapter: pointer to adapter
4378 * @bssid: pointer to mac address
4379 * @pEncryptType: pointer to encryption type
4380 * @mcEncryptType: pointer to multicast encryption type
4381 * @pAuthType: pointer to auth type
4382 *
4383 * Return: 0 on success, error number otherwise
4384 */
4385static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4386 u8 *bssid,
4387 eCsrEncryptionType *pEncryptType,
4388 eCsrEncryptionType *mcEncryptType,
4389 eCsrAuthType *pAuthType,
4390#ifdef WLAN_FEATURE_11W
4391 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4392#endif
4393 uint16_t gen_ie_len, uint8_t *gen_ie)
4394{
4395 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
4396 CDF_STATUS result;
4397 tDot11fIERSN dot11RSNIE;
4398 tDot11fIEWPA dot11WPAIE;
4399 uint32_t i;
4400 uint8_t *pRsnIe;
4401 uint16_t RSNIeLen;
4402 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4403 bool updatePMKCache = false;
4404
4405 /*
4406 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4407 * setting present flag to 0.
4408 */
4409 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4410 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4411
4412 /* Type check */
4413 if (gen_ie[0] == DOT11F_EID_RSN) {
4414 /* Validity checks */
4415 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4416 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4417 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4418 gen_ie_len);
4419 return -EINVAL;
4420 }
4421 /* Skip past the EID byte and length byte */
4422 pRsnIe = gen_ie + 2;
4423 RSNIeLen = gen_ie_len - 2;
4424 /* Unpack the RSN IE */
4425 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4426 pRsnIe, RSNIeLen, &dot11RSNIE);
4427 /* Copy out the encryption and authentication types */
4428 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4429 dot11RSNIE.pwise_cipher_suite_count);
4430 hddLog(LOG1, FL("authentication suite count: %d"),
4431 dot11RSNIE.akm_suite_count);
4432 /*Here we have followed the apple base code,
4433 but probably I suspect we can do something different */
4434 /* dot11RSNIE.akm_suite_count */
4435 /* Just translate the FIRST one */
4436 *pAuthType =
4437 hdd_translate_rsn_to_csr_auth_type(
4438 dot11RSNIE.akm_suites[0]);
4439 /* dot11RSNIE.pwise_cipher_suite_count */
4440 *pEncryptType =
4441 hdd_translate_rsn_to_csr_encryption_type(
4442 dot11RSNIE.pwise_cipher_suites[0]);
4443 /* dot11RSNIE.gp_cipher_suite_count */
4444 *mcEncryptType =
4445 hdd_translate_rsn_to_csr_encryption_type(
4446 dot11RSNIE.gp_cipher_suite);
4447#ifdef WLAN_FEATURE_11W
4448 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4449 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4450#endif
4451 /* Set the PMKSA ID Cache for this interface */
4452 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4453 if (is_zero_ether_addr(bssid)) {
4454 hddLog(LOGE, FL("MAC address is all zeroes"));
4455 break;
4456 }
4457 updatePMKCache = true;
4458 /*
4459 * For right now, I assume setASSOCIATE() has passed
4460 * in the bssid.
4461 */
4462 cdf_mem_copy(PMKIDCache[i].BSSID.bytes,
4463 bssid, ETHER_ADDR_LEN);
4464 cdf_mem_copy(PMKIDCache[i].PMKID,
4465 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4466 }
4467
4468 if (updatePMKCache) {
4469 /*
4470 * Calling csr_roam_set_pmkid_cache to configure the
4471 * PMKIDs into the cache.
4472 */
4473 hddLog(LOG1,
4474 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4475 i);
4476 /* Finally set the PMKSA ID Cache in CSR */
4477 result =
4478 sme_roam_set_pmkid_cache(halHandle,
4479 pAdapter->sessionId,
4480 PMKIDCache,
4481 dot11RSNIE.pmkid_count,
4482 false);
4483 }
4484 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4485 /* Validity checks */
4486 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4487 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4488 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4489 gen_ie_len);
4490 return -EINVAL;
4491 }
4492 /* Skip past the EID and length byte - and four byte WiFi OUI */
4493 pRsnIe = gen_ie + 2 + 4;
4494 RSNIeLen = gen_ie_len - (2 + 4);
4495 /* Unpack the WPA IE */
4496 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4497 pRsnIe, RSNIeLen, &dot11WPAIE);
4498 /* Copy out the encryption and authentication types */
4499 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4500 dot11WPAIE.unicast_cipher_count);
4501 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4502 dot11WPAIE.auth_suite_count);
4503 /* dot11WPAIE.auth_suite_count */
4504 /* Just translate the FIRST one */
4505 *pAuthType =
4506 hdd_translate_wpa_to_csr_auth_type(
4507 dot11WPAIE.auth_suites[0]);
4508 /* dot11WPAIE.unicast_cipher_count */
4509 *pEncryptType =
4510 hdd_translate_wpa_to_csr_encryption_type(
4511 dot11WPAIE.unicast_ciphers[0]);
4512 /* dot11WPAIE.unicast_cipher_count */
4513 *mcEncryptType =
4514 hdd_translate_wpa_to_csr_encryption_type(
4515 dot11WPAIE.multicast_cipher);
4516 } else {
4517 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4518 return -EINVAL;
4519 }
4520 return 0;
4521}
4522
4523/**
4524 * hdd_set_genie_to_csr() - set genie to csr
4525 * @pAdapter: pointer to adapter
4526 * @RSNAuthType: pointer to auth type
4527 *
4528 * Return: 0 on success, error number otherwise
4529 */
4530int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4531{
4532 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4533 uint32_t status = 0;
4534 eCsrEncryptionType RSNEncryptType;
4535 eCsrEncryptionType mcRSNEncryptType;
4536#ifdef WLAN_FEATURE_11W
4537 uint8_t RSNMfpRequired = 0;
4538 uint8_t RSNMfpCapable = 0;
4539#endif
4540 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4541 /* MAC address of assoc peer */
4542 /* But, this routine is only called when we are NOT associated. */
4543 cdf_mem_copy(bssid,
4544 pWextState->roamProfile.BSSIDs.bssid,
4545 sizeof(bssid));
4546 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4547 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4548 /* continue */
4549 } else {
4550 return 0;
4551 }
4552 /* The actual processing may eventually be more extensive than this. */
4553 /* Right now, just consume any PMKIDs that are sent in by the app. */
4554 status = hdd_process_genie(pAdapter, bssid,
4555 &RSNEncryptType,
4556 &mcRSNEncryptType, RSNAuthType,
4557#ifdef WLAN_FEATURE_11W
4558 &RSNMfpRequired, &RSNMfpCapable,
4559#endif
4560 pWextState->WPARSNIE[1] + 2,
4561 pWextState->WPARSNIE);
4562 if (status == 0) {
4563 /*
4564 * Now copy over all the security attributes
4565 * you have parsed out.
4566 */
4567 pWextState->roamProfile.EncryptionType.numEntries = 1;
4568 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4569
4570 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4571 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4572 mcRSNEncryptType;
4573
4574 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
4575 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4576 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4577 /*
4578 * For wpa none supplicant sends the WPA IE with unicast
4579 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4580 * multicast cipher as either AES/TKIP based on group
4581 * cipher configuration mentioned in the
4582 * wpa_supplicant.conf.
4583 */
4584
4585 /* Set the unicast cipher same as multicast cipher */
4586 pWextState->roamProfile.EncryptionType.encryptionType[0]
4587 = mcRSNEncryptType;
4588 }
4589#ifdef WLAN_FEATURE_11W
4590 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4591 RSNMfpRequired, RSNMfpCapable);
4592 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4593 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4594#endif
4595 hddLog(LOG1,
4596 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4597 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4598 }
4599 return 0;
4600}
4601
4602/**
4603 * hdd_set_csr_auth_type() - set csr auth type
4604 * @pAdapter: pointer to adapter
4605 * @RSNAuthType: auth type
4606 *
4607 * Return: 0 on success, error number otherwise
4608 */
4609int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4610{
4611 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4612 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4613 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4614 ENTER();
4615
4616 pRoamProfile->AuthType.numEntries = 1;
4617 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4618 pHddStaCtx->conn_info.authType);
4619
4620 switch (pHddStaCtx->conn_info.authType) {
4621 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4622#ifdef FEATURE_WLAN_ESE
4623 case eCSR_AUTH_TYPE_CCKM_WPA:
4624 case eCSR_AUTH_TYPE_CCKM_RSN:
4625#endif
4626 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4627
4628 pRoamProfile->AuthType.authType[0] =
4629 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4630 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4631
4632#ifdef FEATURE_WLAN_ESE
4633 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4634 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4635 == IW_AUTH_KEY_MGMT_802_1X)) {
4636 hddLog(LOG1,
4637 FL("set authType to CCKM WPA. AKM also 802.1X."));
4638 pRoamProfile->AuthType.authType[0] =
4639 eCSR_AUTH_TYPE_CCKM_WPA;
4640 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4641 hddLog(LOG1,
4642 FL("Last chance to set authType to CCKM WPA."));
4643 pRoamProfile->AuthType.authType[0] =
4644 eCSR_AUTH_TYPE_CCKM_WPA;
4645 } else
4646#endif
4647 if ((pWextState->
4648 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4649 == IW_AUTH_KEY_MGMT_802_1X) {
4650 pRoamProfile->AuthType.authType[0] =
4651 eCSR_AUTH_TYPE_WPA;
4652 } else
4653 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4654 == IW_AUTH_KEY_MGMT_PSK) {
4655 pRoamProfile->AuthType.authType[0] =
4656 eCSR_AUTH_TYPE_WPA_PSK;
4657 } else {
4658 pRoamProfile->AuthType.authType[0] =
4659 eCSR_AUTH_TYPE_WPA_NONE;
4660 }
4661 }
4662 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4663#ifdef FEATURE_WLAN_ESE
4664 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4665 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4666 == IW_AUTH_KEY_MGMT_802_1X)) {
4667 hddLog(LOG1,
4668 FL("set authType to CCKM RSN. AKM also 802.1X."));
4669 pRoamProfile->AuthType.authType[0] =
4670 eCSR_AUTH_TYPE_CCKM_RSN;
4671 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4672 hddLog(LOG1,
4673 FL("Last chance to set authType to CCKM RSN."));
4674 pRoamProfile->AuthType.authType[0] =
4675 eCSR_AUTH_TYPE_CCKM_RSN;
4676 } else
4677#endif
4678
4679#ifdef WLAN_FEATURE_VOWIFI_11R
4680 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4681 ((pWextState->
4682 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4683 == IW_AUTH_KEY_MGMT_802_1X)) {
4684 pRoamProfile->AuthType.authType[0] =
4685 eCSR_AUTH_TYPE_FT_RSN;
4686 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4687 &&
4688 ((pWextState->
4689 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4690 == IW_AUTH_KEY_MGMT_PSK)) {
4691 pRoamProfile->AuthType.authType[0] =
4692 eCSR_AUTH_TYPE_FT_RSN_PSK;
4693 } else
4694#endif
4695
4696#ifdef WLAN_FEATURE_11W
4697 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4698 pRoamProfile->AuthType.authType[0] =
4699 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4700 } else if (RSNAuthType ==
4701 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4702 pRoamProfile->AuthType.authType[0] =
4703 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4704 } else
4705#endif
4706
4707 if ((pWextState->
4708 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4709 == IW_AUTH_KEY_MGMT_802_1X) {
4710 pRoamProfile->AuthType.authType[0] =
4711 eCSR_AUTH_TYPE_RSN;
4712 } else
4713 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4714 == IW_AUTH_KEY_MGMT_PSK) {
4715 pRoamProfile->AuthType.authType[0] =
4716 eCSR_AUTH_TYPE_RSN_PSK;
4717 } else {
4718 pRoamProfile->AuthType.authType[0] =
4719 eCSR_AUTH_TYPE_UNKNOWN;
4720 }
4721 }
4722 break;
4723
4724 case eCSR_AUTH_TYPE_SHARED_KEY:
4725
4726 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4727 break;
4728 default:
4729
4730#ifdef FEATURE_WLAN_ESE
4731 hddLog(LOG1, FL("In default, unknown auth type."));
4732#endif /* FEATURE_WLAN_ESE */
4733 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4734 break;
4735 }
4736
4737 hddLog(LOG1, FL("Set roam Authtype to %d"),
4738 pWextState->roamProfile.AuthType.authType[0]);
4739
4740 EXIT();
4741 return 0;
4742}
4743
4744/**
4745 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4746 * to the CSR roam profile.
4747 *
4748 * @dev: Pointer to the net device.
4749 * @info: Pointer to the iw_request_info.
4750 * @wrqu: Pointer to the iwreq_data.
4751 * @extra: Pointer to the data.
4752 *
4753 * Return: 0 for success, error number on failure
4754 */
4755static int __iw_set_essid(struct net_device *dev,
4756 struct iw_request_info *info,
4757 union iwreq_data *wrqu, char *extra)
4758{
4759 unsigned long rc;
4760 uint32_t status = 0;
4761 hdd_wext_state_t *pWextState;
4762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4763 hdd_context_t *hdd_ctx;
4764 uint32_t roamId;
4765 tCsrRoamProfile *pRoamProfile;
4766 eMib_dot11DesiredBssType connectedBssType;
4767 eCsrAuthType RSNAuthType;
4768 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4769 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4770 int ret;
4771
4772 ENTER();
4773
4774 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4775 ret = wlan_hdd_validate_context(hdd_ctx);
4776 if (0 != ret)
4777 return ret;
4778
4779 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION &&
4780 pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) {
4781 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4782 hdd_device_mode_to_string(pAdapter->device_mode),
4783 pAdapter->device_mode);
4784 return -EINVAL;
4785 }
4786
4787 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4788
4789 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4790 hddLog(LOG2, FL("Counter measure is in progress"));
4791 return -EBUSY;
4792 }
4793 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4794 return -EINVAL;
4795
4796 pRoamProfile = &pWextState->roamProfile;
4797 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4798 (eMib_dot11DesiredBssType_independent ==
4799 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
4800 CDF_STATUS cdf_status;
4801
4802 /* Need to issue a disconnect to CSR. */
4803 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4804 cdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
4805 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4806
4807 if (CDF_STATUS_SUCCESS == cdf_status) {
4808 rc = wait_for_completion_timeout(&pAdapter->
4809 disconnect_comp_var,
4810 msecs_to_jiffies
4811 (WLAN_WAIT_TIME_DISCONNECT));
4812 if (!rc)
4813 hddLog(LOGE, FL("Disconnect event timed out"));
4814 }
4815 }
4816
4817 /*
4818 * when cfg80211 defined, wpa_supplicant wext driver uses
4819 * zero-length, null-string ssid for force disconnection.
4820 * after disconnection (if previously connected) and cleaning ssid,
4821 * driver MUST return success.
4822 */
4823 if (0 == wrqu->essid.length)
4824 return 0;
4825
4826 status = hdd_wmm_get_uapsd_mask(pAdapter,
4827 &pWextState->roamProfile.uapsd_mask);
4828 if (CDF_STATUS_SUCCESS != status)
4829 pWextState->roamProfile.uapsd_mask = 0;
4830
4831 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4832
4833 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4834 wrqu->essid.length;
4835
4836 cdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
4837 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
4838 cdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
4839 ssId), extra, wrqu->essid.length);
4840 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4841 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4842
4843 /* set gen ie */
4844 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4845
4846 /* set auth */
4847 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4848 }
4849#ifdef FEATURE_WLAN_WAPI
4850 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4851 if (pAdapter->wapi_info.nWapiMode) {
4852 switch (pAdapter->wapi_info.wapiAuthMode) {
4853 case WAPI_AUTH_MODE_PSK:
4854 {
4855 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4856 pAdapter->wapi_info.wapiAuthMode);
4857 pRoamProfile->AuthType.numEntries = 1;
4858 pRoamProfile->AuthType.authType[0] =
4859 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4860 break;
4861 }
4862 case WAPI_AUTH_MODE_CERT:
4863 {
4864 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4865 pAdapter->wapi_info.wapiAuthMode);
4866 pRoamProfile->AuthType.numEntries = 1;
4867 pRoamProfile->AuthType.authType[0] =
4868 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4869 break;
4870 }
4871 } /* End of switch */
4872 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4873 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4874 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4875 pRoamProfile->EncryptionType.numEntries = 1;
4876 pRoamProfile->EncryptionType.encryptionType[0] =
4877 eCSR_ENCRYPT_TYPE_WPI;
4878 pRoamProfile->mcEncryptionType.numEntries = 1;
4879 pRoamProfile->mcEncryptionType.encryptionType[0] =
4880 eCSR_ENCRYPT_TYPE_WPI;
4881 }
4882 }
4883#endif /* FEATURE_WLAN_WAPI */
4884 /* if previous genIE is not NULL, update AssocIE */
4885 if (0 != pWextState->genIE.length) {
4886 memset(&pWextState->assocAddIE, 0,
4887 sizeof(pWextState->assocAddIE));
4888 memcpy(pWextState->assocAddIE.addIEdata,
4889 pWextState->genIE.addIEdata, pWextState->genIE.length);
4890 pWextState->assocAddIE.length = pWextState->genIE.length;
4891 pWextState->roamProfile.pAddIEAssoc =
4892 pWextState->assocAddIE.addIEdata;
4893 pWextState->roamProfile.nAddIEAssocLength =
4894 pWextState->assocAddIE.length;
4895
4896 /* clear previous genIE after use it */
4897 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4898 }
4899
4900 /*
4901 * Assumes it is not WPS Association by default, except when
4902 * pAddIEAssoc has WPS IE.
4903 */
4904 pWextState->roamProfile.bWPSAssociation = false;
4905
4906 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4907 pWextState->roamProfile.
4908 nAddIEAssocLength))
4909 pWextState->roamProfile.bWPSAssociation = true;
4910
4911 /* Disable auto BMPS entry by PMC until DHCP is done */
4912 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
4913 true);
4914
4915 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
4916
4917 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
4918 hdd_select_cbmode(pAdapter,
4919 (WLAN_HDD_GET_CTX(pAdapter))->config->
4920 AdHocChannel5G);
4921 }
4922 status = sme_roam_connect(hHal, pAdapter->sessionId,
4923 &(pWextState->roamProfile), &roamId);
4924 pRoamProfile->ChannelInfo.ChannelList = NULL;
4925 pRoamProfile->ChannelInfo.numOfChannels = 0;
4926
4927 EXIT();
4928 return status;
4929}
4930
4931/**
4932 * iw_set_essid() - set essid handler function
4933 * @dev: Pointer to the net device.
4934 * @info: Pointer to the iw_request_info.
4935 * @wrqu: Pointer to the iwreq_data.
4936 * @extra: Pointer to the data.
4937 *
4938 * Return: 0 for success, error number on failure
4939 */
4940int iw_set_essid(struct net_device *dev,
4941 struct iw_request_info *info,
4942 union iwreq_data *wrqu, char *extra)
4943{
4944 int ret;
4945
4946 cds_ssr_protect(__func__);
4947 ret = __iw_set_essid(dev, info, wrqu, extra);
4948 cds_ssr_unprotect(__func__);
4949
4950 return ret;
4951}
4952
4953/**
4954 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
4955 * @dev: pointer to the net device
4956 * @info: pointer to the iw request info
4957 * @dwrq: pointer to iw_point
4958 * @extra: pointer to the data
4959 *
4960 * Return: 0 on success, error number otherwise
4961 */
4962static int __iw_get_essid(struct net_device *dev,
4963 struct iw_request_info *info,
4964 struct iw_point *dwrq, char *extra)
4965{
4966 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4967 hdd_context_t *hdd_ctx;
4968 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4969 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4970 int ret;
4971
4972 ENTER();
4973
4974 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4975 ret = wlan_hdd_validate_context(hdd_ctx);
4976 if (0 != ret)
4977 return ret;
4978
4979 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
4980 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
4981 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
4982 || pHddStaCtx->conn_info.connState ==
4983 eConnectionState_IbssDisconnected)
4984 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
4985 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
4986 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
4987 dwrq->length);
4988 dwrq->flags = 1;
4989 } else {
4990 memset(extra, 0, dwrq->length);
4991 dwrq->length = 0;
4992 dwrq->flags = 0;
4993 }
4994 EXIT();
4995 return 0;
4996}
4997
4998/**
4999 * iw_get_essid() - get essid handler function
5000 * @dev: Pointer to the net device.
5001 * @info: Pointer to the iw_request_info.
5002 * @wrqu: Pointer to the iwreq_data.
5003 * @extra: Pointer to the data.
5004 *
5005 * Return: 0 for success, error number on failure
5006 */
5007int iw_get_essid(struct net_device *dev,
5008 struct iw_request_info *info,
5009 struct iw_point *wrqu, char *extra)
5010{
5011 int ret;
5012
5013 cds_ssr_protect(__func__);
5014 ret = __iw_get_essid(dev, info, wrqu, extra);
5015 cds_ssr_unprotect(__func__);
5016
5017 return ret;
5018}
5019
5020/**
5021 * __iw_set_auth() -
5022 * This function sets the auth type received from the wpa_supplicant
5023 * @dev: pointer to the net device
5024 * @info: pointer to the iw request info
5025 * @wrqu: pointer to iwreq_data
5026 * @extra: pointer to the data
5027 *
5028 * Return: 0 on success, error number otherwise
5029 */
5030static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5031 union iwreq_data *wrqu, char *extra)
5032{
5033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5034 hdd_context_t *hdd_ctx;
5035 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5036 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5037 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5038 eCsrEncryptionType mcEncryptionType;
5039 eCsrEncryptionType ucEncryptionType;
5040 int ret;
5041
5042 ENTER();
5043
5044 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5045 ret = wlan_hdd_validate_context(hdd_ctx);
5046 if (0 != ret)
5047 return ret;
5048
5049 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5050 case IW_AUTH_WPA_VERSION:
5051 pWextState->wpaVersion = wrqu->param.value;
5052 break;
5053
5054 case IW_AUTH_CIPHER_PAIRWISE:
5055 {
5056 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5057 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5058 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5059 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5060 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5061 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5062 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5063 if ((IW_AUTH_KEY_MGMT_802_1X
5064 ==
5065 (pWextState->
5066 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5067 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5068 pHddStaCtx->conn_info.authType))
5069 /*Dynamic WEP key */
5070 ucEncryptionType =
5071 eCSR_ENCRYPT_TYPE_WEP40;
5072 else
5073 /*Static WEP key */
5074 ucEncryptionType =
5075 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5076 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5077 if ((IW_AUTH_KEY_MGMT_802_1X
5078 ==
5079 (pWextState->
5080 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5081 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5082 pHddStaCtx->conn_info.authType))
5083 /*Dynamic WEP key */
5084 ucEncryptionType =
5085 eCSR_ENCRYPT_TYPE_WEP104;
5086 else
5087 /*Static WEP key */
5088 ucEncryptionType =
5089 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5090 } else {
5091 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5092 wrqu->param.value);
5093 return -EINVAL;
5094 }
5095
5096 pRoamProfile->EncryptionType.numEntries = 1;
5097 pRoamProfile->EncryptionType.encryptionType[0] =
5098 ucEncryptionType;
5099 }
5100 break;
5101 case IW_AUTH_CIPHER_GROUP:
5102 {
5103 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5104 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5105 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5106 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5107 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5108 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5109 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5110 if ((IW_AUTH_KEY_MGMT_802_1X
5111 ==
5112 (pWextState->
5113 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5114 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5115 pHddStaCtx->conn_info.authType))
5116 mcEncryptionType =
5117 eCSR_ENCRYPT_TYPE_WEP40;
5118 else
5119 mcEncryptionType =
5120 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5121 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5122 /* Dynamic WEP keys won't work with shared keys */
5123 if ((IW_AUTH_KEY_MGMT_802_1X
5124 ==
5125 (pWextState->
5126 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5127 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5128 pHddStaCtx->conn_info.authType)) {
5129 mcEncryptionType =
5130 eCSR_ENCRYPT_TYPE_WEP104;
5131 } else {
5132 mcEncryptionType =
5133 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5134 }
5135 } else {
5136 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5137 wrqu->param.value);
5138 return -EINVAL;
5139 }
5140
5141 pRoamProfile->mcEncryptionType.numEntries = 1;
5142 pRoamProfile->mcEncryptionType.encryptionType[0] =
5143 mcEncryptionType;
5144 }
5145 break;
5146
5147 case IW_AUTH_80211_AUTH_ALG:
5148 {
5149 /* Save the auth algo here and set auth type to SME Roam profile
5150 in the iw_set_ap_address */
5151 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5152 pHddStaCtx->conn_info.authType =
5153 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5154
5155 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5156 pHddStaCtx->conn_info.authType =
5157 eCSR_AUTH_TYPE_SHARED_KEY;
5158
5159 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5160 /*Not supported */
5161 pHddStaCtx->conn_info.authType =
5162 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5163 pWextState->roamProfile.AuthType.authType[0] =
5164 pHddStaCtx->conn_info.authType;
5165 }
5166 break;
5167
5168 case IW_AUTH_KEY_MGMT:
5169 {
5170#ifdef FEATURE_WLAN_ESE
5171#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5172 /*Check for CCKM AKM type */
5173 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5174 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5175 /* Set the CCKM bit in authKeyMgmt */
5176 /*
5177 * Right now, this breaks all ref to authKeyMgmt because
5178 * our code doesn't realize it is a "bitfield"
5179 */
5180 pWextState->authKeyMgmt |=
5181 IW_AUTH_KEY_MGMT_CCKM;
5182 /* Set the key management to 802.1X */
5183 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5184 pWextState->isESEConnection = true;
5185 /*
5186 * This is test code. I need to actually KNOW whether
5187 * this is an RSN Assoc or WPA.
5188 */
5189 pWextState->collectedAuthType =
5190 eCSR_AUTH_TYPE_CCKM_RSN;
5191 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5192 /* Save the key management */
5193 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5194 pWextState->collectedAuthType =
5195 eCSR_AUTH_TYPE_RSN;
5196 } else
5197 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5198 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5199 /* Save the key management anyway */
5200 pWextState->authKeyMgmt = wrqu->param.value;
5201 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5202 /* Save the key management */
5203 pWextState->authKeyMgmt |=
5204 IW_AUTH_KEY_MGMT_802_1X;
5205 pWextState->collectedAuthType =
5206 eCSR_AUTH_TYPE_RSN;
5207 }
5208#else
5209 /* Save the key management */
5210 pWextState->authKeyMgmt = wrqu->param.value;
5211#endif /* FEATURE_WLAN_ESE */
5212 }
5213 break;
5214
5215 case IW_AUTH_TKIP_COUNTERMEASURES:
5216 {
5217 if (wrqu->param.value) {
5218 hddLog(LOG2,
5219 "Counter Measure started %d",
5220 wrqu->param.value);
5221 pWextState->mTKIPCounterMeasures =
5222 TKIP_COUNTER_MEASURE_STARTED;
5223 } else {
5224 hddLog(LOG2,
5225 "Counter Measure stopped=%d",
5226 wrqu->param.value);
5227 pWextState->mTKIPCounterMeasures =
5228 TKIP_COUNTER_MEASURE_STOPED;
5229 }
5230 }
5231 break;
5232 case IW_AUTH_DROP_UNENCRYPTED:
5233 case IW_AUTH_WPA_ENABLED:
5234 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5235 case IW_AUTH_ROAMING_CONTROL:
5236 case IW_AUTH_PRIVACY_INVOKED:
5237
5238 default:
5239
5240 hddLog(LOGW, FL("called with unsupported auth type %d"),
5241 wrqu->param.flags & IW_AUTH_INDEX);
5242 break;
5243 }
5244
5245 EXIT();
5246 return 0;
5247}
5248
5249/**
5250 * iw_set_auth() - set auth callback function
5251 * @dev: Pointer to the net device.
5252 * @info: Pointer to the iw_request_info.
5253 * @wrqu: Pointer to the iwreq_data.
5254 * @extra: Pointer to the data.
5255 *
5256 * Return: 0 for success, error number on failure.
5257 */
5258int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5259 union iwreq_data *wrqu, char *extra)
5260{
5261 int ret;
5262
5263 cds_ssr_protect(__func__);
5264 ret = __iw_set_auth(dev, info, wrqu, extra);
5265 cds_ssr_unprotect(__func__);
5266
5267 return ret;
5268}
5269
5270/**
5271 * __iw_get_auth() -
5272 * This function returns the auth type to the wpa_supplicant
5273 * @dev: pointer to the net device
5274 * @info: pointer to the iw request info
5275 * @wrqu: pointer to iwreq_data
5276 * @extra: pointer to the data
5277 *
5278 * Return: 0 on success, error number otherwise
5279 */
5280static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5281 union iwreq_data *wrqu, char *extra)
5282{
5283 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5284 hdd_context_t *hdd_ctx;
5285 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5286 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5287 int ret;
5288
5289 ENTER();
5290
5291 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5292 ret = wlan_hdd_validate_context(hdd_ctx);
5293 if (0 != ret)
5294 return ret;
5295
5296 switch (pRoamProfile->negotiatedAuthType) {
5297 case eCSR_AUTH_TYPE_WPA_NONE:
5298 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5299 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5300 break;
5301 case eCSR_AUTH_TYPE_WPA:
5302 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5303 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5304 break;
5305#ifdef WLAN_FEATURE_VOWIFI_11R
5306 case eCSR_AUTH_TYPE_FT_RSN:
5307#endif
5308 case eCSR_AUTH_TYPE_RSN:
5309 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5310 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5311 break;
5312 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5313 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5314 break;
5315 case eCSR_AUTH_TYPE_SHARED_KEY:
5316 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5317 break;
5318 case eCSR_AUTH_TYPE_UNKNOWN:
5319 hddLog(LOG1, FL("called with unknown auth type"));
5320 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5321 break;
5322 case eCSR_AUTH_TYPE_AUTOSWITCH:
5323 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5324 break;
5325 case eCSR_AUTH_TYPE_WPA_PSK:
5326 hddLog(LOG1, FL("called with WPA PSK auth type"));
5327 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5328 return -EIO;
5329#ifdef WLAN_FEATURE_VOWIFI_11R
5330 case eCSR_AUTH_TYPE_FT_RSN_PSK:
5331#endif
5332 case eCSR_AUTH_TYPE_RSN_PSK:
5333#ifdef WLAN_FEATURE_11W
5334 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5335 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5336#endif
5337 hddLog(LOG1, FL("called with RSN PSK auth type"));
5338 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5339 return -EIO;
5340 default:
5341 hddLog(LOGE, FL("called with unknown auth type"));
5342 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5343 return -EIO;
5344 }
5345 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5346 switch (pRoamProfile->negotiatedUCEncryptionType) {
5347 case eCSR_ENCRYPT_TYPE_NONE:
5348 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5349 break;
5350 case eCSR_ENCRYPT_TYPE_WEP40:
5351 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5352 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5353 break;
5354 case eCSR_ENCRYPT_TYPE_TKIP:
5355 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5356 break;
5357 case eCSR_ENCRYPT_TYPE_WEP104:
5358 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5359 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5360 break;
5361 case eCSR_ENCRYPT_TYPE_AES:
5362 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5363 break;
5364 default:
5365 hddLog(LOG1, FL("called with unknown auth type %d"),
5366 pRoamProfile->negotiatedUCEncryptionType);
5367 return -EIO;
5368 }
5369 }
5370
5371 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5372 switch (pRoamProfile->negotiatedMCEncryptionType) {
5373 case eCSR_ENCRYPT_TYPE_NONE:
5374 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5375 break;
5376 case eCSR_ENCRYPT_TYPE_WEP40:
5377 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5378 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5379 break;
5380 case eCSR_ENCRYPT_TYPE_TKIP:
5381 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5382 break;
5383 case eCSR_ENCRYPT_TYPE_WEP104:
5384 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5385 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5386 break;
5387 case eCSR_ENCRYPT_TYPE_AES:
5388 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5389 break;
5390 default:
5391 hddLog(LOG1, FL("called with unknown auth type %d"),
5392 pRoamProfile->negotiatedMCEncryptionType);
5393 return -EIO;
5394 }
5395 }
5396
5397 hddLog(LOG1, FL("called with auth type %d"),
5398 pRoamProfile->AuthType.authType[0]);
5399 EXIT();
5400 return 0;
5401}
5402
5403/**
5404 * iw_get_auth() - get auth callback function
5405 * @dev: Pointer to the net device.
5406 * @info: Pointer to the iw_request_info.
5407 * @wrqu: Pointer to the iwreq_data.
5408 * @extra: Pointer to the data.
5409 *
5410 * Return: 0 for success, error number on failure.
5411 */
5412int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5413 union iwreq_data *wrqu, char *extra)
5414{
5415 int ret;
5416
5417 cds_ssr_protect(__func__);
5418 ret = __iw_get_auth(dev, info, wrqu, extra);
5419 cds_ssr_unprotect(__func__);
5420
5421 return ret;
5422}
5423
5424/**
5425 * __iw_set_ap_address() - set ap address
5426 * @dev: pointer to the net device
5427 * @info: pointer to the iw request info
5428 * @wrqu: pointer to iwreq_data
5429 * @extra: pointer to the data
5430 *
5431 * This function updates the HDD global station context connection info
5432 * BSSID with the MAC address received from the wpa_supplicant.
5433 *
5434 * Return: 0 on success, error number otherwise
5435 */
5436static int __iw_set_ap_address(struct net_device *dev,
5437 struct iw_request_info *info,
5438 union iwreq_data *wrqu, char *extra)
5439{
5440
5441 hdd_adapter_t *adapter;
5442 hdd_context_t *hdd_ctx;
5443 hdd_station_ctx_t *pHddStaCtx =
5444 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5445 uint8_t *pMacAddress = NULL;
5446 int ret;
5447
5448 ENTER();
5449
5450 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5451
5452 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5453 ret = wlan_hdd_validate_context(hdd_ctx);
5454 if (0 != ret)
5455 return ret;
5456
5457 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5458 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
5459 cdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
5460 sizeof(struct cdf_mac_addr));
5461 EXIT();
5462
5463 return 0;
5464}
5465
5466/**
5467 * iw_set_ap_address() - set ap addresses callback function
5468 * @dev: Pointer to the net device.
5469 * @info: Pointer to the iw_request_info.
5470 * @wrqu: Pointer to the iwreq_data.
5471 * @extra: Pointer to the data.
5472 *
5473 * Return: 0 for success, error number on failure.
5474 */
5475int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5476 union iwreq_data *wrqu, char *extra)
5477{
5478 int ret;
5479
5480 cds_ssr_protect(__func__);
5481 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5482 cds_ssr_unprotect(__func__);
5483
5484 return ret;
5485}
5486
5487/**
5488 * __iw_get_ap_address() - get ap address
5489 * @dev: pointer to the net device
5490 * @info: pointer to the iw request info
5491 * @wrqu: pointer to iwreq_data
5492 * @extra: pointer to the data
5493 *
5494 * This function returns currently associated BSSID.
5495 *
5496 * Return: 0 on success, error number otherwise
5497 */
5498static int __iw_get_ap_address(struct net_device *dev,
5499 struct iw_request_info *info,
5500 union iwreq_data *wrqu, char *extra)
5501{
5502 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5503 hdd_context_t *hdd_ctx;
5504 hdd_station_ctx_t *pHddStaCtx =
5505 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5506 int ret;
5507
5508 ENTER();
5509
5510 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5511 ret = wlan_hdd_validate_context(hdd_ctx);
5512 if (0 != ret)
5513 return ret;
5514
5515 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5516 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
5517 cdf_mem_copy(wrqu->ap_addr.sa_data,
5518 pHddStaCtx->conn_info.bssId.bytes,
5519 CDF_MAC_ADDR_SIZE);
5520 } else {
5521 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5522 }
5523 EXIT();
5524 return 0;
5525}
5526
5527/**
5528 * iw_get_ap_address() - get ap addresses callback function
5529 * @dev: Pointer to the net device.
5530 * @info: Pointer to the iw_request_info.
5531 * @wrqu: Pointer to the iwreq_data.
5532 * @extra: Pointer to the data.
5533 *
5534 * Return: 0 for success, error number on failure.
5535 */
5536int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5537 union iwreq_data *wrqu, char *extra)
5538{
5539 int ret;
5540
5541 cds_ssr_protect(__func__);
5542 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5543 cds_ssr_unprotect(__func__);
5544
5545 return ret;
5546}