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