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