xref: /wlan-dirver/qcacld-3.0/core/sme/src/csr/csr_util.c (revision 6147c58dff00905c59dc4f432e6487aa8d278bb6)
1 /*
2  * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /** ------------------------------------------------------------------------- *
29     ------------------------------------------------------------------------- *
30 
31     \file csr_util.c
32 
33     Implementation supporting routines for CSR.
34    ========================================================================== */
35 
36 #include "ani_global.h"
37 
38 #include "csr_support.h"
39 #include "csr_inside_api.h"
40 #include "sms_debug.h"
41 #include "sme_qos_internal.h"
42 #include "wma_types.h"
43 #include "cds_utils.h"
44 #include "cds_concurrency.h"
45 
46 
47 uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE] = {
48 	{0x00, 0x50, 0xf2, 0x00}
49 	,
50 	{0x00, 0x50, 0xf2, 0x01}
51 	,
52 	{0x00, 0x50, 0xf2, 0x02}
53 	,
54 	{0x00, 0x50, 0xf2, 0x03}
55 	,
56 	{0x00, 0x50, 0xf2, 0x04}
57 	,
58 	{0x00, 0x50, 0xf2, 0x05}
59 	,
60 #ifdef FEATURE_WLAN_ESE
61 	{0x00, 0x40, 0x96, 0x00}
62 	,                       /* CCKM */
63 #endif /* FEATURE_WLAN_ESE */
64 };
65 
66 uint8_t csr_rsn_oui[][CSR_RSN_OUI_SIZE] = {
67 	{0x00, 0x0F, 0xAC, 0x00}
68 	,                       /* group cipher */
69 	{0x00, 0x0F, 0xAC, 0x01}
70 	,                       /* WEP-40 or RSN */
71 	{0x00, 0x0F, 0xAC, 0x02}
72 	,                       /* TKIP or RSN-PSK */
73 	{0x00, 0x0F, 0xAC, 0x03}
74 	,                       /* Reserved */
75 	{0x00, 0x0F, 0xAC, 0x04}
76 	,                       /* AES-CCMP */
77 	{0x00, 0x0F, 0xAC, 0x05}
78 	,                       /* WEP-104 */
79 	{0x00, 0x40, 0x96, 0x00}
80 	,                       /* CCKM */
81 	{0x00, 0x0F, 0xAC, 0x06}
82 	,                       /* BIP (encryption type) or
83 				RSN-PSK-SHA256 (authentication type) */
84 	/* RSN-8021X-SHA256 (authentication type) */
85 	{0x00, 0x0F, 0xAC, 0x05}
86 };
87 
88 #ifdef FEATURE_WLAN_WAPI
89 uint8_t csr_wapi_oui[][CSR_WAPI_OUI_SIZE] = {
90 	{0x00, 0x14, 0x72, 0x00}
91 	,                       /* Reserved */
92 	{0x00, 0x14, 0x72, 0x01}
93 	,                       /* WAI certificate or SMS4 */
94 	{0x00, 0x14, 0x72, 0x02} /* WAI PSK */
95 };
96 #endif /* FEATURE_WLAN_WAPI */
97 uint8_t csr_wme_info_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
98 uint8_t csr_wme_parm_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
99 
100 /* ////////////////////////////////////////////////////////////////////// */
101 
102 /**
103  * \var g_phy_rates_suppt
104  *
105  * \brief Rate support lookup table
106  *
107  *
108  * This is a  lookup table indexing rates &  configuration parameters to
109  * support.  Given a rate (in  unites of 0.5Mpbs) & three bools (MIMO
110  * Enabled, Channel  Bonding Enabled, & Concatenation  Enabled), one can
111  * determine  whether  the given  rate  is  supported  by computing  two
112  * indices.  The  first maps  the rate to  table row as  indicated below
113  * (i.e. eHddSuppRate_6Mbps maps to  row zero, eHddSuppRate_9Mbps to row
114  * 1, and so on).  Index two can be computed like so:
115  *
116  * \code
117  *  idx2 = ( fEsf  ? 0x4 : 0x0 ) |
118  *         ( fCb   ? 0x2 : 0x0 ) |
119  *         ( fMimo ? 0x1 : 0x0 );
120  * \endcode
121  *
122  *
123  * Given that:
124  *
125  *  \code
126  *  fSupported = g_phy_rates_suppt[idx1][idx2];
127  *  \endcode
128  *
129  *
130  * This table is based on  the document "PHY Supported Rates.doc".  This
131  * table is  permissive in that a  rate is reflected  as being supported
132  * even  when turning  off an  enabled feature  would be  required.  For
133  * instance, "PHY Supported Rates"  lists 42Mpbs as unsupported when CB,
134  * ESF, &  MIMO are all  on.  However,  if we turn  off either of  CB or
135  * MIMO, it then becomes supported.   Therefore, we mark it as supported
136  * even in index 7 of this table.
137  *
138  *
139  */
140 
141 static const bool g_phy_rates_suppt[24][8] = {
142 
143 	/* SSF   SSF    SSF    SSF    ESF    ESF    ESF    ESF */
144 	/* SIMO  MIMO   SIMO   MIMO   SIMO   MIMO   SIMO   MIMO */
145 	/* No CB No CB  CB     CB     No CB  No CB  CB     CB */
146 	{true, true, true, true, true, true, true, true},       /* 6Mbps */
147 	{true, true, true, true, true, true, true, true},       /* 9Mbps */
148 	{true, true, true, true, true, true, true, true},       /* 12Mbps */
149 	{true, true, true, true, true, true, true, true},       /* 18Mbps */
150 	{false, false, true, true, false, false, true, true},   /* 20Mbps */
151 	{true, true, true, true, true, true, true, true},       /* 24Mbps */
152 	{true, true, true, true, true, true, true, true},       /* 36Mbps */
153 	{false, false, true, true, false, true, true, true},    /* 40Mbps */
154 	{false, false, true, true, false, true, true, true},    /* 42Mbps */
155 	{true, true, true, true, true, true, true, true},       /* 48Mbps */
156 	{true, true, true, true, true, true, true, true},       /* 54Mbps */
157 	{false, true, true, true, false, true, true, true},     /* 72Mbps */
158 	{false, false, true, true, false, true, true, true},    /* 80Mbps */
159 	{false, false, true, true, false, true, true, true},    /* 84Mbps */
160 	{false, true, true, true, false, true, true, true},     /* 96Mbps */
161 	{false, true, true, true, false, true, true, true},     /* 108Mbps */
162 	{false, false, true, true, false, true, true, true},    /* 120Mbps */
163 	{false, false, true, true, false, true, true, true},    /* 126Mbps */
164 	{false, false, false, true, false, false, false, true}, /* 144Mbps */
165 	{false, false, false, true, false, false, false, true}, /* 160Mbps */
166 	{false, false, false, true, false, false, false, true}, /* 168Mbps */
167 	{false, false, false, true, false, false, false, true}, /* 192Mbps */
168 	{false, false, false, true, false, false, false, true}, /* 216Mbps */
169 	{false, false, false, true, false, false, false, true}, /* 240Mbps */
170 
171 };
172 
173 #define CASE_RETURN_STR(n) {\
174 	case (n): return (# n);\
175 }
176 
177 const char *get_e_roam_cmd_status_str(eRoamCmdStatus val)
178 {
179 	switch (val) {
180 		CASE_RETURN_STR(eCSR_ROAM_CANCELLED);
181 		CASE_RETURN_STR(eCSR_ROAM_FAILED);
182 		CASE_RETURN_STR(eCSR_ROAM_ROAMING_START);
183 		CASE_RETURN_STR(eCSR_ROAM_ROAMING_COMPLETION);
184 		CASE_RETURN_STR(eCSR_ROAM_CONNECT_COMPLETION);
185 		CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_START);
186 		CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_COMPLETION);
187 		CASE_RETURN_STR(eCSR_ROAM_DISASSOCIATED);
188 		CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_FAILURE);
189 		CASE_RETURN_STR(eCSR_ROAM_SHOULD_ROAM);
190 		CASE_RETURN_STR(eCSR_ROAM_SCAN_FOUND_NEW_BSS);
191 		CASE_RETURN_STR(eCSR_ROAM_LOSTLINK);
192 		CASE_RETURN_STR(eCSR_ROAM_LOSTLINK_DETECTED);
193 		CASE_RETURN_STR(eCSR_ROAM_MIC_ERROR_IND);
194 		CASE_RETURN_STR(eCSR_ROAM_IBSS_IND);
195 		CASE_RETURN_STR(eCSR_ROAM_CONNECT_STATUS_UPDATE);
196 		CASE_RETURN_STR(eCSR_ROAM_GEN_INFO);
197 		CASE_RETURN_STR(eCSR_ROAM_SET_KEY_COMPLETE);
198 		CASE_RETURN_STR(eCSR_ROAM_IBSS_LEAVE);
199 		CASE_RETURN_STR(eCSR_ROAM_INFRA_IND);
200 		CASE_RETURN_STR(eCSR_ROAM_WPS_PBC_PROBE_REQ_IND);
201 		CASE_RETURN_STR(eCSR_ROAM_FT_RESPONSE);
202 		CASE_RETURN_STR(eCSR_ROAM_FT_START);
203 		CASE_RETURN_STR(eCSR_ROAM_REMAIN_CHAN_READY);
204 		CASE_RETURN_STR(eCSR_ROAM_SESSION_OPENED);
205 		CASE_RETURN_STR(eCSR_ROAM_FT_REASSOC_FAILED);
206 		CASE_RETURN_STR(eCSR_ROAM_PMK_NOTIFY);
207 #ifdef FEATURE_WLAN_LFR_METRICS
208 		CASE_RETURN_STR(eCSR_ROAM_PREAUTH_INIT_NOTIFY);
209 		CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_SUCCESS);
210 		CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_FAILURE);
211 		CASE_RETURN_STR(eCSR_ROAM_HANDOVER_SUCCESS);
212 #endif
213 #ifdef FEATURE_WLAN_TDLS
214 		CASE_RETURN_STR(eCSR_ROAM_TDLS_STATUS_UPDATE);
215 		CASE_RETURN_STR(eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND);
216 #endif
217 		CASE_RETURN_STR(eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS);
218 		CASE_RETURN_STR(eCSR_ROAM_SEND_P2P_STOP_BSS);
219 #ifdef WLAN_FEATURE_11W
220 		CASE_RETURN_STR(eCSR_ROAM_UNPROT_MGMT_FRAME_IND);
221 #endif
222 #ifdef WLAN_FEATURE_RMC
223 		CASE_RETURN_STR(eCSR_ROAM_IBSS_PEER_INFO_COMPLETE);
224 #endif
225 #ifdef FEATURE_WLAN_ESE
226 		CASE_RETURN_STR(eCSR_ROAM_TSM_IE_IND);
227 		CASE_RETURN_STR(eCSR_ROAM_CCKM_PREAUTH_NOTIFY);
228 		CASE_RETURN_STR(eCSR_ROAM_ESE_ADJ_AP_REPORT_IND);
229 		CASE_RETURN_STR(eCSR_ROAM_ESE_BCN_REPORT_IND);
230 #endif /* FEATURE_WLAN_ESE */
231 	default:
232 		return "unknown";
233 	}
234 }
235 
236 const char *get_e_csr_roam_result_str(eCsrRoamResult val)
237 {
238 	switch (val) {
239 		CASE_RETURN_STR(eCSR_ROAM_RESULT_NONE);
240 		CASE_RETURN_STR(eCSR_ROAM_RESULT_FAILURE);
241 		CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOCIATED);
242 		CASE_RETURN_STR(eCSR_ROAM_RESULT_NOT_ASSOCIATED);
243 		CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_FAILURE);
244 		CASE_RETURN_STR(eCSR_ROAM_RESULT_FORCED);
245 		CASE_RETURN_STR(eCSR_ROAM_RESULT_DISASSOC_IND);
246 		CASE_RETURN_STR(eCSR_ROAM_RESULT_DEAUTH_IND);
247 		CASE_RETURN_STR(eCSR_ROAM_RESULT_CAP_CHANGED);
248 		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_CONNECT);
249 		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_INACTIVE);
250 		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_NEW_PEER);
251 		CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_COALESCED);
252 	default:
253 		return "unknown";
254 	}
255 }
256 
257 bool csr_get_bss_id_bss_desc(tHalHandle hHal, tSirBssDescription *pSirBssDesc,
258 			     struct qdf_mac_addr *pBssId)
259 {
260 	qdf_mem_copy(pBssId, &pSirBssDesc->bssId[0],
261 			sizeof(struct qdf_mac_addr));
262 	return true;
263 }
264 
265 bool csr_is_bss_id_equal(tHalHandle hHal, tSirBssDescription *pSirBssDesc1,
266 			 tSirBssDescription *pSirBssDesc2)
267 {
268 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
269 	bool fEqual = false;
270 	struct qdf_mac_addr bssId1;
271 	struct qdf_mac_addr bssId2;
272 
273 	do {
274 		if (!pSirBssDesc1)
275 			break;
276 		if (!pSirBssDesc2)
277 			break;
278 
279 		if (!csr_get_bss_id_bss_desc(pMac, pSirBssDesc1, &bssId1))
280 			break;
281 		if (!csr_get_bss_id_bss_desc(pMac, pSirBssDesc2, &bssId2))
282 			break;
283 
284 		fEqual = qdf_is_macaddr_equal(&bssId1, &bssId2);
285 	} while (0);
286 
287 	return fEqual;
288 }
289 
290 bool csr_is_conn_state_connected_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
291 {
292 	return eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED ==
293 		pMac->roam.roamSession[sessionId].connectState;
294 }
295 
296 bool csr_is_conn_state_disconnected_ibss(tpAniSirGlobal pMac,
297 					 uint32_t sessionId)
298 {
299 	return eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED ==
300 		pMac->roam.roamSession[sessionId].connectState;
301 }
302 
303 bool csr_is_conn_state_connected_infra(tpAniSirGlobal pMac, uint32_t sessionId)
304 {
305 	return eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
306 		pMac->roam.roamSession[sessionId].connectState;
307 }
308 
309 bool csr_is_conn_state_connected(tpAniSirGlobal pMac, uint32_t sessionId)
310 {
311 	if (csr_is_conn_state_connected_ibss(pMac, sessionId)
312 	    || csr_is_conn_state_connected_infra(pMac, sessionId)
313 	    || csr_is_conn_state_connected_wds(pMac, sessionId))
314 		return true;
315 	else
316 		return false;
317 }
318 
319 bool csr_is_conn_state_infra(tpAniSirGlobal pMac, uint32_t sessionId)
320 {
321 	return csr_is_conn_state_connected_infra(pMac, sessionId);
322 }
323 
324 bool csr_is_conn_state_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
325 {
326 	return csr_is_conn_state_connected_ibss(pMac, sessionId) ||
327 	       csr_is_conn_state_disconnected_ibss(pMac, sessionId);
328 }
329 
330 bool csr_is_conn_state_connected_wds(tpAniSirGlobal pMac, uint32_t sessionId)
331 {
332 	return eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED ==
333 		pMac->roam.roamSession[sessionId].connectState;
334 }
335 
336 bool csr_is_conn_state_connected_infra_ap(tpAniSirGlobal pMac,
337 					  uint32_t sessionId)
338 {
339 	return (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
340 		 pMac->roam.roamSession[sessionId].connectState) ||
341 	       (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED ==
342 		 pMac->roam.roamSession[sessionId].connectState);
343 }
344 
345 bool csr_is_conn_state_disconnected_wds(tpAniSirGlobal pMac, uint32_t sessionId)
346 {
347 	return eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED ==
348 		pMac->roam.roamSession[sessionId].connectState;
349 }
350 
351 bool csr_is_conn_state_wds(tpAniSirGlobal pMac, uint32_t sessionId)
352 {
353 	return csr_is_conn_state_connected_wds(pMac, sessionId) ||
354 	       csr_is_conn_state_disconnected_wds(pMac, sessionId);
355 }
356 
357 static bool csr_is_conn_state_ap(tpAniSirGlobal pMac, uint32_t sessionId)
358 {
359 	tCsrRoamSession *pSession;
360 	pSession = CSR_GET_SESSION(pMac, sessionId);
361 	if (!pSession)
362 		return false;
363 	if (CSR_IS_INFRA_AP(&pSession->connectedProfile))
364 		return true;
365 	return false;
366 }
367 
368 bool csr_is_any_session_in_connect_state(tpAniSirGlobal pMac)
369 {
370 	uint32_t i;
371 	bool fRc = false;
372 
373 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
374 		if (CSR_IS_SESSION_VALID(pMac, i) &&
375 		    (csr_is_conn_state_infra(pMac, i)
376 		     || csr_is_conn_state_ibss(pMac, i)
377 		     || csr_is_conn_state_ap(pMac, i))) {
378 			fRc = true;
379 			break;
380 		}
381 	}
382 
383 	return fRc;
384 }
385 
386 int8_t csr_get_infra_session_id(tpAniSirGlobal pMac)
387 {
388 	uint8_t i;
389 	int8_t sessionid = -1;
390 
391 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
392 		if (CSR_IS_SESSION_VALID(pMac, i)
393 		    && csr_is_conn_state_infra(pMac, i)) {
394 			sessionid = i;
395 			break;
396 		}
397 	}
398 
399 	return sessionid;
400 }
401 
402 uint8_t csr_get_infra_operation_channel(tpAniSirGlobal pMac, uint8_t sessionId)
403 {
404 	uint8_t channel;
405 
406 	if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
407 		channel =
408 			pMac->roam.roamSession[sessionId].connectedProfile.
409 			operationChannel;
410 	} else {
411 		channel = 0;
412 	}
413 	return channel;
414 }
415 
416 bool csr_is_session_client_and_connected(tpAniSirGlobal pMac, uint8_t sessionId)
417 {
418 	tCsrRoamSession *pSession = NULL;
419 	if (CSR_IS_SESSION_VALID(pMac, sessionId)
420 	    && csr_is_conn_state_infra(pMac, sessionId)) {
421 		pSession = CSR_GET_SESSION(pMac, sessionId);
422 		if (NULL != pSession->pCurRoamProfile) {
423 			if ((pSession->pCurRoamProfile->csrPersona ==
424 			     QDF_STA_MODE)
425 			    || (pSession->pCurRoamProfile->csrPersona ==
426 				QDF_P2P_CLIENT_MODE))
427 				return true;
428 		}
429 	}
430 	return false;
431 }
432 
433 /**
434  * csr_get_concurrent_operation_channel() - To get concurrent operating channel
435  * @mac_ctx: Pointer to mac context
436  *
437  * This routine will return operating channel on FIRST BSS that is
438  * active/operating to be used for concurrency mode.
439  * If other BSS is not up or not connected it will return 0
440  *
441  * Return: uint8_t
442  */
443 uint8_t csr_get_concurrent_operation_channel(tpAniSirGlobal mac_ctx)
444 {
445 	tCsrRoamSession *session = NULL;
446 	uint8_t i = 0;
447 	enum tQDF_ADAPTER_MODE persona;
448 
449 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
450 		if (!CSR_IS_SESSION_VALID(mac_ctx, i))
451 			continue;
452 		session = CSR_GET_SESSION(mac_ctx, i);
453 		if (NULL == session->pCurRoamProfile)
454 			continue;
455 		persona = session->pCurRoamProfile->csrPersona;
456 		if ((((persona == QDF_STA_MODE) ||
457 			(persona == QDF_P2P_CLIENT_MODE)) &&
458 			(session->connectState ==
459 				eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) ||
460 			(((persona == QDF_P2P_GO_MODE) ||
461 				(persona == QDF_SAP_MODE))
462 				 && (session->connectState !=
463 					 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)))
464 			return session->connectedProfile.operationChannel;
465 
466 	}
467 	return 0;
468 }
469 
470 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
471 
472 #define HALF_BW_OF(eCSR_bw_val) ((eCSR_bw_val)/2)
473 
474 /* calculation of center channel based on V/HT BW and WIFI channel bw=5MHz) */
475 
476 #define CSR_GET_HT40_PLUS_CCH(och) ((och)+2)
477 #define CSR_GET_HT40_MINUS_CCH(och) ((och)-2)
478 
479 #define CSR_GET_HT80_PLUS_LL_CCH(och) ((och)+6)
480 #define CSR_GET_HT80_PLUS_HL_CCH(och) ((och)+2)
481 #define CSR_GET_HT80_MINUS_LH_CCH(och) ((och)-2)
482 #define CSR_GET_HT80_MINUS_HH_CCH(och) ((och)-6)
483 
484 /**
485  * csr_get_ch_from_ht_profile() - to get channel from HT profile
486  * @pMac: pointer to Mac context
487  * @htp: pointer to HT profile
488  * @och: operating channel
489  * @cfreq: channel frequency
490  * @hbw: half bandwidth
491  *
492  * This function will fill half bandwidth and channel frequency based
493  * on the HT profile
494  *
495  * Return: none
496  */
497 static void csr_get_ch_from_ht_profile(tpAniSirGlobal pMac,
498 				       tCsrRoamHTProfile *htp,
499 				       uint16_t och, uint16_t *cfreq,
500 				       uint16_t *hbw)
501 {
502 	uint16_t cch, ch_bond;
503 
504 	if (och > 14)
505 		ch_bond = pMac->roam.configParam.channelBondingMode5GHz;
506 	else
507 		ch_bond = pMac->roam.configParam.channelBondingMode24GHz;
508 
509 	cch = och;
510 	*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
511 
512 	if (!ch_bond)
513 		goto ret;
514 
515 	sms_log(pMac, LOG1, FL("##HTC: %d scbw: %d rcbw: %d sco: %d"
516 				"VHTC: %d apc: %d apbw: %d"
517 			      ),
518 			htp->htCapability, htp->htSupportedChannelWidthSet,
519 			htp->htRecommendedTxWidthSet,
520 			htp->htSecondaryChannelOffset,
521 			htp->vhtCapability, htp->apCenterChan, htp->apChanWidth
522 	       );
523 
524 	if (htp->vhtCapability) {
525 		cch = htp->apCenterChan;
526 		if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
527 			*hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
528 		else if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
529 			*hbw = HALF_BW_OF(eCSR_BW_160MHz_VAL);
530 
531 		if (!*hbw && htp->htCapability) {
532 			if (htp->htSupportedChannelWidthSet ==
533 				eHT_CHANNEL_WIDTH_40MHZ)
534 				*hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
535 			else
536 				*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
537 		}
538 	} else if (htp->htCapability) {
539 			if (htp->htSupportedChannelWidthSet ==
540 					eHT_CHANNEL_WIDTH_40MHZ) {
541 				*hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
542 				if (htp->htSecondaryChannelOffset ==
543 					PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
544 					cch = CSR_GET_HT40_PLUS_CCH(och);
545 				else if (htp->htSecondaryChannelOffset ==
546 					PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
547 					cch = CSR_GET_HT40_MINUS_CCH(och);
548 			} else {
549 				cch = och;
550 				*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
551 			}
552 		}
553 
554 ret:
555 	*cfreq = cds_chan_to_freq(cch);
556 	return;
557 }
558 
559 /**
560  * csr_calc_chb_for_sap_phymode() - to calc channel bandwidth for sap phymode
561  * @mac_ctx: pointer to mac context
562  * @sap_ch: SAP operating channel
563  * @sap_phymode: SAP physical mode
564  * @sap_cch: concurrency channel
565  * @sap_hbw: SAP half bw
566  * @chb: channel bandwidth
567  *
568  * This routine is called to calculate channel bandwidth
569  *
570  * Return: none
571  */
572 static void csr_calc_chb_for_sap_phymode(tpAniSirGlobal mac_ctx,
573 		uint16_t *sap_ch, eCsrPhyMode *sap_phymode,
574 		uint16_t *sap_cch, uint16_t *sap_hbw, uint8_t *chb)
575 {
576 	if (*sap_phymode == eCSR_DOT11_MODE_11n ||
577 			*sap_phymode == eCSR_DOT11_MODE_11n_ONLY) {
578 
579 		*sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
580 		if (*chb == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
581 			*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
582 		else if (*chb == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
583 			*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
584 
585 	} else if (*sap_phymode == eCSR_DOT11_MODE_11ac ||
586 			*sap_phymode == eCSR_DOT11_MODE_11ac_ONLY) {
587 		/*11AC only 80/40/20 Mhz supported in Rome */
588 		if (mac_ctx->roam.configParam.nVhtChannelWidth ==
589 				(WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1)) {
590 			*sap_hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
591 			if (*chb ==
592 				(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1))
593 				*sap_cch = CSR_GET_HT80_PLUS_LL_CCH(*sap_ch);
594 			else if (*chb ==
595 				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
596 				     - 1))
597 				*sap_cch = CSR_GET_HT80_PLUS_HL_CCH(*sap_ch);
598 			else if (*chb ==
599 				 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
600 				     - 1))
601 				*sap_cch = CSR_GET_HT80_MINUS_LH_CCH(*sap_ch);
602 			else if (*chb ==
603 				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
604 				     - 1))
605 				*sap_cch = CSR_GET_HT80_MINUS_HH_CCH(*sap_ch);
606 		} else {
607 			*sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
608 			if (*chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW
609 					- 1))
610 				*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
611 			else if (*chb ==
612 				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
613 				     - 1))
614 				*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
615 			else if (*chb ==
616 				(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
617 				     - 1))
618 				*sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
619 			else if (*chb ==
620 				(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
621 				     - 1))
622 				*sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
623 		}
624 	}
625 }
626 
627 /**
628  * csr_handle_conc_chnl_overlap_for_sap_go - To handle overlap for AP+AP
629  * @mac_ctx: pointer to mac context
630  * @session: Current session
631  * @sap_ch: SAP/GO operating channel
632  * @sap_hbw: SAP/GO half bw
633  * @sap_cfreq: SAP/GO channel frequency
634  * @intf_ch: concurrent SAP/GO operating channel
635  * @intf_hbw: concurrent SAP/GO half bw
636  * @intf_cfreq: concurrent SAP/GO channel frequency
637  *
638  * This routine is called to check if one SAP/GO channel is overlapping with
639  * other SAP/GO channel
640  *
641  * Return: none
642  */
643 static void csr_handle_conc_chnl_overlap_for_sap_go(tpAniSirGlobal mac_ctx,
644 		tCsrRoamSession *session,
645 		uint16_t *sap_ch, uint16_t *sap_hbw, uint16_t *sap_cfreq,
646 		uint16_t *intf_ch, uint16_t *intf_hbw, uint16_t *intf_cfreq)
647 {
648 	/*
649 	 * if conc_custom_rule1 is defined then we don't
650 	 * want p2pgo to follow SAP's channel or SAP to
651 	 * follow P2PGO's channel.
652 	 */
653 	if (0 == mac_ctx->roam.configParam.conc_custom_rule1 &&
654 		0 == mac_ctx->roam.configParam.conc_custom_rule2) {
655 		if (*sap_ch == 0) {
656 			*sap_ch = session->connectedProfile.operationChannel;
657 			csr_get_ch_from_ht_profile(mac_ctx,
658 				&session->connectedProfile.HTProfile,
659 				*sap_ch, sap_cfreq, sap_hbw);
660 		} else if (*sap_ch !=
661 				session->connectedProfile.operationChannel) {
662 			*intf_ch = session->connectedProfile.operationChannel;
663 			csr_get_ch_from_ht_profile(mac_ctx,
664 					&session->connectedProfile.HTProfile,
665 					*intf_ch, intf_cfreq, intf_hbw);
666 		}
667 	} else if (*sap_ch == 0 &&
668 			(session->pCurRoamProfile->csrPersona ==
669 					QDF_SAP_MODE)) {
670 		*sap_ch = session->connectedProfile.operationChannel;
671 		csr_get_ch_from_ht_profile(mac_ctx,
672 				&session->connectedProfile.HTProfile,
673 				*sap_ch, sap_cfreq, sap_hbw);
674 	}
675 }
676 
677 
678 /**
679  * csr_check_concurrent_channel_overlap() - To check concurrent overlap chnls
680  * @mac_ctx: Pointer to mac context
681  * @sap_ch: SAP channel
682  * @sap_phymode: SAP phy mode
683  * @cc_switch_mode: concurrent switch mode
684  *
685  * This routine will be called to check concurrent overlap channels
686  *
687  * Return: uint16_t
688  */
689 uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx,
690 			uint16_t sap_ch, eCsrPhyMode sap_phymode,
691 			uint8_t cc_switch_mode)
692 {
693 	tCsrRoamSession *session = NULL;
694 	uint8_t i = 0, chb = PHY_SINGLE_CHANNEL_CENTERED;
695 	uint16_t intf_ch = 0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0;
696 	uint16_t sap_cfreq = 0;
697 	uint16_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq, sap_cch = 0;
698 	QDF_STATUS status;
699 
700 	sms_log(mac_ctx, LOG1, FL("sap_ch:%d sap_phymode:%d"),
701 		sap_ch, sap_phymode);
702 
703 	if (mac_ctx->roam.configParam.cc_switch_mode ==
704 			QDF_MCC_TO_SCC_SWITCH_DISABLE)
705 		return 0;
706 
707 	if (sap_ch != 0) {
708 		sap_cch = sap_ch;
709 		sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
710 
711 		if (sap_ch > 14)
712 			chb = mac_ctx->roam.configParam.channelBondingMode5GHz;
713 		else
714 			chb = mac_ctx->roam.configParam.channelBondingMode24GHz;
715 
716 		if (chb)
717 			csr_calc_chb_for_sap_phymode(mac_ctx, &sap_ch,
718 					&sap_phymode, &sap_cch, &sap_hbw, &chb);
719 		sap_cfreq = cds_chan_to_freq(sap_cch);
720 	}
721 
722 	sms_log(mac_ctx, LOG1,
723 		FL("sap_ch:%d sap_phymode:%d sap_cch:%d sap_hbw:%d chb:%d"),
724 		sap_ch, sap_phymode, sap_cch, sap_hbw, chb);
725 
726 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
727 		if (!CSR_IS_SESSION_VALID(mac_ctx, i))
728 			continue;
729 
730 		session = CSR_GET_SESSION(mac_ctx, i);
731 		if (NULL == session->pCurRoamProfile)
732 			continue;
733 		if (((session->pCurRoamProfile->csrPersona == QDF_STA_MODE) ||
734 			(session->pCurRoamProfile->csrPersona ==
735 				QDF_P2P_CLIENT_MODE)) &&
736 			(session->connectState ==
737 				eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) {
738 			intf_ch = session->connectedProfile.operationChannel;
739 			csr_get_ch_from_ht_profile(mac_ctx,
740 				&session->connectedProfile.HTProfile,
741 				intf_ch, &intf_cfreq, &intf_hbw);
742 			sms_log(mac_ctx, LOG1,
743 				FL("%d: intf_ch:%d intf_cfreq:%d intf_hbw:%d"),
744 				i, intf_ch, intf_cfreq, intf_hbw);
745 		} else if (((session->pCurRoamProfile->csrPersona ==
746 					QDF_P2P_GO_MODE) ||
747 				(session->pCurRoamProfile->csrPersona ==
748 					QDF_SAP_MODE)) &&
749 				(session->connectState !=
750 					eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
751 				if (session->ch_switch_in_progress)
752 					continue;
753 
754 				csr_handle_conc_chnl_overlap_for_sap_go(mac_ctx,
755 					session, &sap_ch, &sap_hbw, &sap_cfreq,
756 					&intf_ch, &intf_hbw, &intf_cfreq);
757 
758 				sms_log(mac_ctx, LOG1,
759 					FL("%d: sap_ch:%d sap_hbw:%d sap_cfreq:%d intf_ch:%d intf_hbw:%d, intf_cfreq:%d"),
760 					i, sap_ch, sap_hbw, sap_cfreq,
761 					intf_ch, intf_hbw, intf_cfreq);
762 		}
763 	}
764 
765 	sms_log(mac_ctx, LOG1,
766 		FL("intf_ch:%d sap_ch:%d cc_switch_mode:%d"),
767 		intf_ch, sap_ch, cc_switch_mode);
768 
769 	if (intf_ch && sap_ch != intf_ch &&
770 	    cc_switch_mode != QDF_MCC_TO_SCC_SWITCH_FORCE &&
771 	    cc_switch_mode !=
772 	    QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION &&
773 	    cc_switch_mode !=
774 	    QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) {
775 		sap_lfreq = sap_cfreq - sap_hbw;
776 		sap_hfreq = sap_cfreq + sap_hbw;
777 		intf_lfreq = intf_cfreq - intf_hbw;
778 		intf_hfreq = intf_cfreq + intf_hbw;
779 
780 		sms_log(mac_ctx, LOGE,
781 			FL("\nSAP:  OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d\n"
782 			"INTF: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d"),
783 			sap_ch, cds_chan_to_freq(sap_ch),
784 			cds_freq_to_chan(sap_cfreq), sap_cfreq, sap_hbw * 2,
785 			sap_lfreq, sap_hfreq, intf_ch,
786 			cds_chan_to_freq(intf_ch), cds_freq_to_chan(intf_cfreq),
787 			intf_cfreq, intf_hbw * 2, intf_lfreq, intf_hfreq);
788 
789 		if (!(((sap_lfreq > intf_lfreq && sap_lfreq < intf_hfreq) ||
790 			(sap_hfreq > intf_lfreq && sap_hfreq < intf_hfreq)) ||
791 			((intf_lfreq > sap_lfreq && intf_lfreq < sap_hfreq) ||
792 			(intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq))))
793 			intf_ch = 0;
794 	} else if (intf_ch && sap_ch != intf_ch &&
795 		((cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE) ||
796 		(cc_switch_mode ==
797 			QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) ||
798 		(cc_switch_mode ==
799 			QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL))) {
800 		if (!((intf_ch < 14 && sap_ch < 14) ||
801 			(intf_ch > 14 && sap_ch > 14)))
802 			intf_ch = 0;
803 		else if (cc_switch_mode ==
804 			QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) {
805 			status =
806 			    cds_get_sap_mandatory_channel((uint32_t *)&intf_ch);
807 			if (QDF_IS_STATUS_ERROR(status)) {
808 				sms_log(mac_ctx, LOGE,
809 						FL("no mandatory channel"));
810 				intf_ch = sap_ch;
811 			}
812 		}
813 	} else if ((intf_ch == sap_ch) && (cc_switch_mode ==
814 				QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)) {
815 		if (cds_chan_to_band(intf_ch) == CDS_BAND_2GHZ) {
816 			status =
817 				cds_get_sap_mandatory_channel(
818 						(uint32_t *)&intf_ch);
819 			if (QDF_IS_STATUS_ERROR(status)) {
820 				sms_log(mac_ctx, LOGE,
821 						FL("no mandatory channel"));
822 				intf_ch = sap_ch;
823 			}
824 		}
825 	}
826 
827 	if (intf_ch == sap_ch)
828 		intf_ch = 0;
829 
830 	sms_log(mac_ctx, LOGE, FL("##Concurrent Channels %s Interfering"),
831 		intf_ch == 0 ? "Not" : "Are");
832 	return intf_ch;
833 }
834 #endif
835 
836 bool csr_is_all_session_disconnected(tpAniSirGlobal pMac)
837 {
838 	uint32_t i;
839 	bool fRc = true;
840 
841 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
842 		if (CSR_IS_SESSION_VALID(pMac, i)
843 		    && !csr_is_conn_state_disconnected(pMac, i)) {
844 			fRc = false;
845 			break;
846 		}
847 	}
848 
849 	return fRc;
850 }
851 
852 /**
853  * csr_is_sta_session_connected() - to find if concurrent sta is active
854  * @mac_ctx: pointer to mac context
855  *
856  * This function will iterate through each session and check if sta
857  * session exist and active
858  *
859  * Return: true or false
860  */
861 bool csr_is_sta_session_connected(tpAniSirGlobal mac_ctx)
862 {
863 	uint32_t i;
864 	tCsrRoamSession *pSession = NULL;
865 
866 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
867 		if (CSR_IS_SESSION_VALID(mac_ctx, i) &&
868 			!csr_is_conn_state_disconnected(mac_ctx, i)) {
869 			pSession = CSR_GET_SESSION(mac_ctx, i);
870 
871 			if ((NULL != pSession->pCurRoamProfile) &&
872 				(QDF_STA_MODE ==
873 					pSession->pCurRoamProfile->csrPersona))
874 				return true;
875 		}
876 	}
877 
878 	return false;
879 }
880 
881 /**
882  * csr_is_p2p_session_connected() - to find if any p2p session is active
883  * @mac_ctx: pointer to mac context
884  *
885  * This function will iterate through each session and check if any p2p
886  * session exist and active
887  *
888  * Return: true or false
889  */
890 bool csr_is_p2p_session_connected(tpAniSirGlobal pMac)
891 {
892 	uint32_t i;
893 	tCsrRoamSession *pSession = NULL;
894 	enum tQDF_ADAPTER_MODE persona;
895 
896 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
897 		if (!CSR_IS_SESSION_VALID(pMac, i))
898 			continue;
899 
900 		if (csr_is_conn_state_disconnected(pMac, i))
901 			continue;
902 
903 		pSession = CSR_GET_SESSION(pMac, i);
904 		if (pSession->pCurRoamProfile == NULL)
905 			continue;
906 
907 		persona = pSession->pCurRoamProfile->csrPersona;
908 		if (QDF_P2P_CLIENT_MODE == persona ||
909 				QDF_P2P_GO_MODE == persona)
910 			return true;
911 	}
912 
913 	return false;
914 }
915 
916 bool csr_is_any_session_connected(tpAniSirGlobal pMac)
917 {
918 	uint32_t i, count;
919 	bool fRc = false;
920 
921 	count = 0;
922 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
923 		if (CSR_IS_SESSION_VALID(pMac, i)
924 		    && !csr_is_conn_state_disconnected(pMac, i))
925 			count++;
926 	}
927 
928 	if (count > 0)
929 		fRc = true;
930 	return fRc;
931 }
932 
933 bool csr_is_infra_connected(tpAniSirGlobal pMac)
934 {
935 	uint32_t i;
936 	bool fRc = false;
937 
938 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
939 		if (CSR_IS_SESSION_VALID(pMac, i)
940 		    && csr_is_conn_state_connected_infra(pMac, i)) {
941 			fRc = true;
942 			break;
943 		}
944 	}
945 
946 	return fRc;
947 }
948 
949 bool csr_is_concurrent_infra_connected(tpAniSirGlobal pMac)
950 {
951 	uint32_t i, noOfConnectedInfra = 0;
952 
953 	bool fRc = false;
954 
955 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
956 		if (CSR_IS_SESSION_VALID(pMac, i)
957 		    && csr_is_conn_state_connected_infra(pMac, i)) {
958 			++noOfConnectedInfra;
959 		}
960 	}
961 
962 	/* More than one Infra Sta Connected */
963 	if (noOfConnectedInfra > 1)
964 		fRc = true;
965 	return fRc;
966 }
967 
968 bool csr_is_ibss_started(tpAniSirGlobal pMac)
969 {
970 	uint32_t i;
971 	bool fRc = false;
972 
973 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
974 		if (CSR_IS_SESSION_VALID(pMac, i)
975 		    && csr_is_conn_state_ibss(pMac, i)) {
976 			fRc = true;
977 			break;
978 		}
979 	}
980 
981 	return fRc;
982 }
983 
984 bool csr_is_concurrent_session_running(tpAniSirGlobal pMac)
985 {
986 	uint32_t sessionId, noOfCocurrentSession = 0;
987 	eCsrConnectState connectState;
988 
989 	bool fRc = false;
990 
991 	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
992 		if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
993 			connectState =
994 				pMac->roam.roamSession[sessionId].connectState;
995 			if ((eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
996 			     connectState)
997 			    || (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
998 				connectState)
999 			    || (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED ==
1000 				connectState)) {
1001 				++noOfCocurrentSession;
1002 			}
1003 		}
1004 	}
1005 
1006 	/* More than one session is Up and Running */
1007 	if (noOfCocurrentSession > 1)
1008 		fRc = true;
1009 	return fRc;
1010 }
1011 
1012 bool csr_is_infra_ap_started(tpAniSirGlobal pMac)
1013 {
1014 	uint32_t sessionId;
1015 	bool fRc = false;
1016 
1017 	for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
1018 		if (CSR_IS_SESSION_VALID(pMac, sessionId)
1019 		    && (csr_is_conn_state_connected_infra_ap(pMac, sessionId))) {
1020 			fRc = true;
1021 			break;
1022 		}
1023 	}
1024 
1025 	return fRc;
1026 
1027 }
1028 
1029 bool csr_is_conn_state_disconnected(tpAniSirGlobal pMac, uint32_t sessionId)
1030 {
1031 	return eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED ==
1032 	       pMac->roam.roamSession[sessionId].connectState;
1033 }
1034 
1035 /**
1036  * csr_is_valid_mc_concurrent_session() - To check concurren session is valid
1037  * @mac_ctx: pointer to mac context
1038  * @session_id: session id
1039  * @bss_descr: bss description
1040  *
1041  * This function validates the concurrent session
1042  *
1043  * Return: true or false
1044  */
1045 bool csr_is_valid_mc_concurrent_session(tpAniSirGlobal mac_ctx,
1046 		uint32_t session_id,
1047 		tSirBssDescription *bss_descr)
1048 {
1049 	tCsrRoamSession *pSession = NULL;
1050 
1051 	/* Check for MCC support */
1052 	if (!mac_ctx->roam.configParam.fenableMCCMode)
1053 		return false;
1054 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id))
1055 		return false;
1056 	/* Validate BeaconInterval */
1057 	pSession = CSR_GET_SESSION(mac_ctx, session_id);
1058 	if (NULL == pSession->pCurRoamProfile)
1059 		return false;
1060 	if (QDF_STATUS_SUCCESS == csr_validate_mcc_beacon_interval(mac_ctx,
1061 					bss_descr->channelId,
1062 					&bss_descr->beaconInterval, session_id,
1063 					pSession->pCurRoamProfile->csrPersona))
1064 		return true;
1065 	return false;
1066 }
1067 
1068 static tSirMacCapabilityInfo csr_get_bss_capabilities(tSirBssDescription *
1069 						      pSirBssDesc)
1070 {
1071 	tSirMacCapabilityInfo dot11Caps;
1072 
1073 	/* tSirMacCapabilityInfo is 16-bit */
1074 	qdf_get_u16((uint8_t *) &pSirBssDesc->capabilityInfo,
1075 		    (uint16_t *) &dot11Caps);
1076 
1077 	return dot11Caps;
1078 }
1079 
1080 bool csr_is_infra_bss_desc(tSirBssDescription *pSirBssDesc)
1081 {
1082 	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
1083 
1084 	return (bool) dot11Caps.ess;
1085 }
1086 
1087 bool csr_is_ibss_bss_desc(tSirBssDescription *pSirBssDesc)
1088 {
1089 	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
1090 
1091 	return (bool) dot11Caps.ibss;
1092 }
1093 
1094 static bool csr_is_qos_bss_desc(tSirBssDescription *pSirBssDesc)
1095 {
1096 	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
1097 
1098 	return (bool) dot11Caps.qos;
1099 }
1100 
1101 bool csr_is_privacy(tSirBssDescription *pSirBssDesc)
1102 {
1103 	tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
1104 
1105 	return (bool) dot11Caps.privacy;
1106 }
1107 
1108 bool csr_is11d_supported(tpAniSirGlobal pMac)
1109 {
1110 	return pMac->roam.configParam.Is11dSupportEnabled;
1111 }
1112 
1113 bool csr_is11h_supported(tpAniSirGlobal pMac)
1114 {
1115 	return pMac->roam.configParam.Is11hSupportEnabled;
1116 }
1117 
1118 bool csr_is11e_supported(tpAniSirGlobal pMac)
1119 {
1120 	return pMac->roam.configParam.Is11eSupportEnabled;
1121 }
1122 
1123 bool csr_is_mcc_supported(tpAniSirGlobal pMac)
1124 {
1125 	return pMac->roam.configParam.fenableMCCMode;
1126 
1127 }
1128 
1129 bool csr_is_wmm_supported(tpAniSirGlobal pMac)
1130 {
1131 	if (eCsrRoamWmmNoQos == pMac->roam.configParam.WMMSupportMode)
1132 		return false;
1133 	else
1134 		return true;
1135 }
1136 
1137 /* pIes is the IEs for pSirBssDesc2 */
1138 bool csr_is_ssid_equal(tHalHandle hHal, tSirBssDescription *pSirBssDesc1,
1139 		       tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2)
1140 {
1141 	bool fEqual = false;
1142 	tSirMacSSid Ssid1, Ssid2;
1143 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1144 	tDot11fBeaconIEs *pIes1 = NULL;
1145 	tDot11fBeaconIEs *pIesLocal = pIes2;
1146 
1147 	do {
1148 		if ((NULL == pSirBssDesc1) || (NULL == pSirBssDesc2))
1149 			break;
1150 		if (!pIesLocal
1151 		    &&
1152 		    !QDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies
1153 						   (pMac, pSirBssDesc2,
1154 						    &pIesLocal))) {
1155 			sms_log(pMac, LOGE, FL("  fail to parse IEs"));
1156 			break;
1157 		}
1158 		if (!QDF_IS_STATUS_SUCCESS
1159 			(csr_get_parsed_bss_description_ies(pMac,
1160 				pSirBssDesc1, &pIes1))) {
1161 			break;
1162 		}
1163 		if ((!pIes1->SSID.present) || (!pIesLocal->SSID.present))
1164 			break;
1165 		if (pIes1->SSID.num_ssid != pIesLocal->SSID.num_ssid)
1166 			break;
1167 		qdf_mem_copy(Ssid1.ssId, pIes1->SSID.ssid,
1168 			     pIes1->SSID.num_ssid);
1169 		qdf_mem_copy(Ssid2.ssId, pIesLocal->SSID.ssid,
1170 			     pIesLocal->SSID.num_ssid);
1171 
1172 		fEqual = (!qdf_mem_cmp(Ssid1.ssId, Ssid2.ssId,
1173 					pIesLocal->SSID.num_ssid));
1174 
1175 	} while (0);
1176 	if (pIes1)
1177 		qdf_mem_free(pIes1);
1178 	if (pIesLocal && !pIes2)
1179 		qdf_mem_free(pIesLocal);
1180 
1181 	return fEqual;
1182 }
1183 
1184 /* pIes can be passed in as NULL if the caller doesn't have one prepared */
1185 static bool csr_is_bss_description_wme(tHalHandle hHal,
1186 				       tSirBssDescription *pSirBssDesc,
1187 				       tDot11fBeaconIEs *pIes)
1188 {
1189 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1190 	/* Assume that WME is found... */
1191 	bool fWme = true;
1192 	tDot11fBeaconIEs *pIesTemp = pIes;
1193 
1194 	do {
1195 		if (pIesTemp == NULL) {
1196 			if (!QDF_IS_STATUS_SUCCESS
1197 				    (csr_get_parsed_bss_description_ies
1198 					    (pMac, pSirBssDesc, &pIesTemp))) {
1199 				fWme = false;
1200 				break;
1201 			}
1202 		}
1203 		/* if the Wme Info IE is found, then WME is supported... */
1204 		if (CSR_IS_QOS_BSS(pIesTemp))
1205 			break;
1206 		/* if none of these are found, then WME is NOT supported... */
1207 		fWme = false;
1208 	} while (0);
1209 	if (!csr_is_wmm_supported(pMac) && fWme) {
1210 		if (!pIesTemp->HTCaps.present) {
1211 			fWme = false;
1212 		}
1213 	}
1214 	if ((pIes == NULL) && (NULL != pIesTemp)) {
1215 		/* we allocate memory here so free it before returning */
1216 		qdf_mem_free(pIesTemp);
1217 	}
1218 
1219 	return fWme;
1220 }
1221 
1222 eCsrMediaAccessType csr_get_qo_s_from_bss_desc(tHalHandle hHal,
1223 					       tSirBssDescription *pSirBssDesc,
1224 					       tDot11fBeaconIEs *pIes)
1225 {
1226 	eCsrMediaAccessType qosType = eCSR_MEDIUM_ACCESS_DCF;
1227 
1228 	if (NULL == pIes) {
1229 		QDF_ASSERT(pIes != NULL);
1230 		return qosType;
1231 	}
1232 
1233 	do {
1234 		/* if we find WMM in the Bss Description, then we let this */
1235 		/* override and use WMM. */
1236 		if (csr_is_bss_description_wme(hHal, pSirBssDesc, pIes)) {
1237 			qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
1238 		} else {
1239 			/* if the QoS bit is on, then the AP is advertising 11E QoS... */
1240 			if (csr_is_qos_bss_desc(pSirBssDesc)) {
1241 				qosType = eCSR_MEDIUM_ACCESS_11e_eDCF;
1242 			} else {
1243 				qosType = eCSR_MEDIUM_ACCESS_DCF;
1244 			}
1245 			/* scale back based on the types turned on for the adapter... */
1246 			if (eCSR_MEDIUM_ACCESS_11e_eDCF == qosType
1247 			    && !csr_is11e_supported(hHal)) {
1248 				qosType = eCSR_MEDIUM_ACCESS_DCF;
1249 			}
1250 		}
1251 
1252 	} while (0);
1253 
1254 	return qosType;
1255 }
1256 
1257 /* Caller allocates memory for pIEStruct */
1258 QDF_STATUS csr_parse_bss_description_ies(tHalHandle hHal,
1259 					  tSirBssDescription *pBssDesc,
1260 					  tDot11fBeaconIEs *pIEStruct)
1261 {
1262 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1263 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1264 	int ieLen =
1265 		(int)(pBssDesc->length + sizeof(pBssDesc->length) -
1266 		      GET_FIELD_OFFSET(tSirBssDescription, ieFields));
1267 
1268 	if (ieLen > 0 && pIEStruct) {
1269 		if (!DOT11F_FAILED
1270 			    (dot11f_unpack_beacon_i_es
1271 				    (pMac, (uint8_t *) pBssDesc->ieFields, ieLen,
1272 				    pIEStruct))) {
1273 			status = QDF_STATUS_SUCCESS;
1274 		}
1275 	}
1276 
1277 	return status;
1278 }
1279 
1280 /* This function will allocate memory for the parsed IEs to the caller. Caller must free the memory */
1281 /* after it is done with the data only if this function succeeds */
1282 QDF_STATUS csr_get_parsed_bss_description_ies(tHalHandle hHal,
1283 					       tSirBssDescription *pBssDesc,
1284 					       tDot11fBeaconIEs **ppIEStruct)
1285 {
1286 	QDF_STATUS status = QDF_STATUS_E_INVAL;
1287 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1288 
1289 	if (pBssDesc && ppIEStruct) {
1290 		*ppIEStruct = qdf_mem_malloc(sizeof(tDot11fBeaconIEs));
1291 		if ((*ppIEStruct) != NULL) {
1292 			qdf_mem_set((void *)*ppIEStruct,
1293 				    sizeof(tDot11fBeaconIEs), 0);
1294 			status =
1295 				csr_parse_bss_description_ies(hHal, pBssDesc,
1296 							       *ppIEStruct);
1297 			if (!QDF_IS_STATUS_SUCCESS(status)) {
1298 				qdf_mem_free(*ppIEStruct);
1299 				*ppIEStruct = NULL;
1300 			}
1301 		} else {
1302 			sms_log(pMac, LOGE, FL(" failed to allocate memory"));
1303 			QDF_ASSERT(0);
1304 			return QDF_STATUS_E_NOMEM;
1305 		}
1306 	}
1307 
1308 	return status;
1309 }
1310 
1311 bool csr_is_nullssid(uint8_t *pBssSsid, uint8_t len)
1312 {
1313 	bool fNullSsid = false;
1314 
1315 	uint32_t SsidLength;
1316 	uint8_t *pSsidStr;
1317 
1318 	do {
1319 		if (0 == len) {
1320 			fNullSsid = true;
1321 			break;
1322 		}
1323 		/* Consider 0 or space for hidden SSID */
1324 		if (0 == pBssSsid[0]) {
1325 			fNullSsid = true;
1326 			break;
1327 		}
1328 
1329 		SsidLength = len;
1330 		pSsidStr = pBssSsid;
1331 
1332 		while (SsidLength) {
1333 			if (*pSsidStr)
1334 				break;
1335 
1336 			pSsidStr++;
1337 			SsidLength--;
1338 		}
1339 
1340 		if (0 == SsidLength) {
1341 			fNullSsid = true;
1342 			break;
1343 		}
1344 	} while (0);
1345 
1346 	return fNullSsid;
1347 }
1348 
1349 uint32_t csr_get_frag_thresh(tHalHandle hHal)
1350 {
1351 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1352 
1353 	return pMac->roam.configParam.FragmentationThreshold;
1354 }
1355 
1356 uint32_t csr_get_rts_thresh(tHalHandle hHal)
1357 {
1358 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1359 
1360 	return pMac->roam.configParam.RTSThreshold;
1361 }
1362 
1363 static eCsrPhyMode csr_translate_to_phy_mode_from_bss_desc(
1364 						tSirBssDescription *pSirBssDesc)
1365 {
1366 	eCsrPhyMode phyMode;
1367 
1368 	switch (pSirBssDesc->nwType) {
1369 	case eSIR_11A_NW_TYPE:
1370 		phyMode = eCSR_DOT11_MODE_11a;
1371 		break;
1372 
1373 	case eSIR_11B_NW_TYPE:
1374 		phyMode = eCSR_DOT11_MODE_11b;
1375 		break;
1376 
1377 	case eSIR_11G_NW_TYPE:
1378 		phyMode = eCSR_DOT11_MODE_11g;
1379 		break;
1380 
1381 	case eSIR_11N_NW_TYPE:
1382 		phyMode = eCSR_DOT11_MODE_11n;
1383 		break;
1384 	case eSIR_11AC_NW_TYPE:
1385 	default:
1386 		phyMode = eCSR_DOT11_MODE_11ac;
1387 		break;
1388 	}
1389 	return phyMode;
1390 }
1391 
1392 uint32_t csr_translate_to_wni_cfg_dot11_mode(tpAniSirGlobal pMac,
1393 					     eCsrCfgDot11Mode csrDot11Mode)
1394 {
1395 	uint32_t ret;
1396 
1397 	switch (csrDot11Mode) {
1398 	case eCSR_CFG_DOT11_MODE_AUTO:
1399 		sms_log(pMac, LOGW,
1400 			FL("  Warning: sees eCSR_CFG_DOT11_MODE_AUTO "));
1401 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
1402 			ret = WNI_CFG_DOT11_MODE_11AC;
1403 		else
1404 			ret = WNI_CFG_DOT11_MODE_11N;
1405 		break;
1406 	case eCSR_CFG_DOT11_MODE_11A:
1407 		ret = WNI_CFG_DOT11_MODE_11A;
1408 		break;
1409 	case eCSR_CFG_DOT11_MODE_11B:
1410 		ret = WNI_CFG_DOT11_MODE_11B;
1411 		break;
1412 	case eCSR_CFG_DOT11_MODE_11G:
1413 		ret = WNI_CFG_DOT11_MODE_11G;
1414 		break;
1415 	case eCSR_CFG_DOT11_MODE_11N:
1416 		ret = WNI_CFG_DOT11_MODE_11N;
1417 		break;
1418 	case eCSR_CFG_DOT11_MODE_11G_ONLY:
1419 		ret = WNI_CFG_DOT11_MODE_11G_ONLY;
1420 		break;
1421 	case eCSR_CFG_DOT11_MODE_11N_ONLY:
1422 		ret = WNI_CFG_DOT11_MODE_11N_ONLY;
1423 		break;
1424 	case eCSR_CFG_DOT11_MODE_11AC_ONLY:
1425 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
1426 			ret = WNI_CFG_DOT11_MODE_11AC_ONLY;
1427 		else
1428 			ret = WNI_CFG_DOT11_MODE_11N;
1429 		break;
1430 	case eCSR_CFG_DOT11_MODE_11AC:
1431 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
1432 			ret = WNI_CFG_DOT11_MODE_11AC;
1433 		else
1434 			ret = WNI_CFG_DOT11_MODE_11N;
1435 		break;
1436 	default:
1437 		sms_log(pMac, LOGW, FL("doesn't expect %d as csrDo11Mode"),
1438 			csrDot11Mode);
1439 		if (eCSR_BAND_24 == pMac->roam.configParam.eBand) {
1440 			ret = WNI_CFG_DOT11_MODE_11G;
1441 		} else {
1442 			ret = WNI_CFG_DOT11_MODE_11A;
1443 		}
1444 		break;
1445 	}
1446 
1447 	return ret;
1448 }
1449 
1450 /**
1451  * csr_get_phy_mode_from_bss() - Get Phy Mode
1452  * @pMac:           Global MAC context
1453  * @pBSSDescription: BSS Descriptor
1454  * @pPhyMode:        Physical Mode
1455  * @pIes:            Pointer to the IE fields
1456  *
1457  * This function should only return the super set of supported modes
1458  * 11n implies 11b/g/a/n.
1459  *
1460  * Return: success
1461  **/
1462 QDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac,
1463 		tSirBssDescription *pBSSDescription,
1464 		eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes)
1465 {
1466 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1467 	eCsrPhyMode phyMode =
1468 		csr_translate_to_phy_mode_from_bss_desc(pBSSDescription);
1469 
1470 	if (pIes) {
1471 		if (pIes->HTCaps.present) {
1472 			phyMode = eCSR_DOT11_MODE_11n;
1473 			if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) ||
1474 				IS_BSS_VHT_CAPABLE(pIes->vendor_vht_ie.VHTCaps))
1475 				phyMode = eCSR_DOT11_MODE_11ac;
1476 		}
1477 		*pPhyMode = phyMode;
1478 	}
1479 
1480 	return status;
1481 }
1482 
1483 /**
1484  * csr_get_phy_mode_in_use() - to get phymode
1485  * @phyModeIn: physical mode
1486  * @bssPhyMode: physical mode in bss
1487  * @f5GhzBand: 5Ghz band
1488  * @pCfgDot11ModeToUse: dot11 mode in use
1489  *
1490  * This function returns the correct eCSR_CFG_DOT11_MODE is the two phyModes
1491  * matches. bssPhyMode is the mode derived from the BSS description
1492  * f5GhzBand is derived from the channel id of BSS description
1493  *
1494  * Return: true or false
1495  */
1496 static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn,
1497 				    eCsrPhyMode bssPhyMode,
1498 				    bool f5GhzBand,
1499 				    eCsrCfgDot11Mode *pCfgDot11ModeToUse)
1500 {
1501 	bool fMatch = false;
1502 	eCsrCfgDot11Mode cfgDot11Mode;
1503 	cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1504 
1505 	switch (phyModeIn) {
1506 	/* 11a or 11b or 11g */
1507 	case eCSR_DOT11_MODE_abg:
1508 		fMatch = true;
1509 		if (f5GhzBand)
1510 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1511 		else if (eCSR_DOT11_MODE_11b == bssPhyMode)
1512 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1513 		else
1514 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1515 		break;
1516 
1517 	case eCSR_DOT11_MODE_11a:
1518 		if (f5GhzBand) {
1519 			fMatch = true;
1520 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1521 		}
1522 		break;
1523 
1524 	case eCSR_DOT11_MODE_11g:
1525 		if (!f5GhzBand) {
1526 			fMatch = true;
1527 			if (eCSR_DOT11_MODE_11b == bssPhyMode)
1528 				cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1529 			else
1530 				cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1531 		}
1532 		break;
1533 
1534 	case eCSR_DOT11_MODE_11g_ONLY:
1535 		if (eCSR_DOT11_MODE_11g == bssPhyMode) {
1536 			fMatch = true;
1537 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1538 		}
1539 		break;
1540 
1541 	case eCSR_DOT11_MODE_11b:
1542 		if (!f5GhzBand) {
1543 			fMatch = true;
1544 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1545 		}
1546 		break;
1547 
1548 	case eCSR_DOT11_MODE_11b_ONLY:
1549 		if (eCSR_DOT11_MODE_11b == bssPhyMode) {
1550 			fMatch = true;
1551 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1552 		}
1553 		break;
1554 
1555 	case eCSR_DOT11_MODE_11n:
1556 		fMatch = true;
1557 		switch (bssPhyMode) {
1558 		case eCSR_DOT11_MODE_11g:
1559 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1560 			break;
1561 		case eCSR_DOT11_MODE_11b:
1562 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1563 			break;
1564 		case eCSR_DOT11_MODE_11a:
1565 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1566 			break;
1567 		case eCSR_DOT11_MODE_11n:
1568 		case eCSR_DOT11_MODE_11ac:
1569 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1570 			break;
1571 
1572 		default:
1573 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
1574 			break;
1575 		}
1576 		break;
1577 
1578 	case eCSR_DOT11_MODE_11n_ONLY:
1579 		if ((eCSR_DOT11_MODE_11n == bssPhyMode)) {
1580 			fMatch = true;
1581 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1582 
1583 		}
1584 
1585 		break;
1586 	case eCSR_DOT11_MODE_11ac:
1587 		fMatch = true;
1588 		switch (bssPhyMode) {
1589 		case eCSR_DOT11_MODE_11g:
1590 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1591 			break;
1592 		case eCSR_DOT11_MODE_11b:
1593 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1594 			break;
1595 		case eCSR_DOT11_MODE_11a:
1596 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1597 			break;
1598 		case eCSR_DOT11_MODE_11n:
1599 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1600 			break;
1601 		case eCSR_DOT11_MODE_11ac:
1602 		default:
1603 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
1604 			break;
1605 		}
1606 		break;
1607 
1608 	case eCSR_DOT11_MODE_11ac_ONLY:
1609 		if ((eCSR_DOT11_MODE_11ac == bssPhyMode)) {
1610 			fMatch = true;
1611 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
1612 		}
1613 		break;
1614 
1615 	default:
1616 		fMatch = true;
1617 		switch (bssPhyMode) {
1618 		case eCSR_DOT11_MODE_11g:
1619 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1620 			break;
1621 		case eCSR_DOT11_MODE_11b:
1622 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1623 			break;
1624 		case eCSR_DOT11_MODE_11a:
1625 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1626 			break;
1627 		case eCSR_DOT11_MODE_11n:
1628 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1629 			break;
1630 		case eCSR_DOT11_MODE_11ac:
1631 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
1632 			break;
1633 		default:
1634 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
1635 			break;
1636 		}
1637 		break;
1638 	}
1639 
1640 	if (fMatch && pCfgDot11ModeToUse) {
1641 		if (cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC
1642 		    && (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)))
1643 			*pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
1644 		else
1645 			*pCfgDot11ModeToUse = cfgDot11Mode;
1646 	}
1647 	return fMatch;
1648 }
1649 
1650 /**
1651  * csr_is_phy_mode_match() - to find if phy mode matches
1652  * @pMac: pointer to mac context
1653  * @phyMode: physical mode
1654  * @pSirBssDesc: bss description
1655  * @pProfile: pointer to roam profile
1656  * @pReturnCfgDot11Mode: dot1 mode to return
1657  * @pIes: pointer to IEs
1658  *
1659  * This function decides whether the one of the bit of phyMode is matching the
1660  * mode in the BSS and allowed by the user setting
1661  *
1662  * Return: true or false based on mode that fits the criteria
1663  */
1664 bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode,
1665 			   tSirBssDescription *pSirBssDesc,
1666 			   tCsrRoamProfile *pProfile,
1667 			   eCsrCfgDot11Mode *pReturnCfgDot11Mode,
1668 			   tDot11fBeaconIEs *pIes)
1669 {
1670 	bool fMatch = false;
1671 	eCsrPhyMode phyModeInBssDesc = eCSR_DOT11_MODE_AUTO, phyMode2;
1672 	eCsrCfgDot11Mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_AUTO;
1673 	uint32_t bitMask, loopCount;
1674 
1675 	if (!QDF_IS_STATUS_SUCCESS(csr_get_phy_mode_from_bss(pMac, pSirBssDesc,
1676 					&phyModeInBssDesc, pIes)))
1677 		return fMatch;
1678 
1679 	if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
1680 		if (eCSR_CFG_DOT11_MODE_ABG ==
1681 				pMac->roam.configParam.uCfgDot11Mode)
1682 			phyMode = eCSR_DOT11_MODE_abg;
1683 		else if (eCSR_CFG_DOT11_MODE_AUTO ==
1684 				pMac->roam.configParam.uCfgDot11Mode)
1685 			phyMode = eCSR_DOT11_MODE_11ac;
1686 		else
1687 			/* user's pick */
1688 			phyMode = pMac->roam.configParam.phyMode;
1689 	}
1690 
1691 	if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
1692 		if (0 != phyMode) {
1693 			if (eCSR_DOT11_MODE_AUTO & phyMode) {
1694 				phyMode2 =
1695 					eCSR_DOT11_MODE_AUTO & phyMode;
1696 			}
1697 		} else {
1698 			phyMode2 = phyMode;
1699 		}
1700 		fMatch = csr_get_phy_mode_in_use(phyMode2, phyModeInBssDesc,
1701 				CDS_IS_CHANNEL_5GHZ(pSirBssDesc->channelId),
1702 				&cfgDot11ModeToUse);
1703 	} else {
1704 		bitMask = 1;
1705 		loopCount = 0;
1706 		while (loopCount < eCSR_NUM_PHY_MODE) {
1707 			phyMode2 = (phyMode & (bitMask << loopCount++));
1708 			if (0 != phyMode2 && csr_get_phy_mode_in_use(phyMode2,
1709 						phyModeInBssDesc,
1710 						CDS_IS_CHANNEL_5GHZ
1711 						(pSirBssDesc->channelId),
1712 						&cfgDot11ModeToUse)) {
1713 				fMatch = true;
1714 				break;
1715 			}
1716 		}
1717 	}
1718 	if (fMatch && pReturnCfgDot11Mode) {
1719 		if (pProfile) {
1720 			/*
1721 			 * IEEE 11n spec (8.4.3): HT STA shall
1722 			 * eliminate TKIP as a choice for the pairwise
1723 			 * cipher suite if CCMP is advertised by the AP
1724 			 * or if the AP included an HT capabilities
1725 			 * element in its Beacons and Probe Response.
1726 			 */
1727 			if ((!CSR_IS_11n_ALLOWED(
1728 					pProfile->negotiatedUCEncryptionType))
1729 					&& ((eCSR_CFG_DOT11_MODE_11N ==
1730 						cfgDot11ModeToUse) ||
1731 					(eCSR_CFG_DOT11_MODE_11AC ==
1732 						cfgDot11ModeToUse))) {
1733 				/* We cannot do 11n here */
1734 				if (!CDS_IS_CHANNEL_5GHZ
1735 						(pSirBssDesc->channelId)) {
1736 					cfgDot11ModeToUse =
1737 						eCSR_CFG_DOT11_MODE_11G;
1738 				} else {
1739 					cfgDot11ModeToUse =
1740 						eCSR_CFG_DOT11_MODE_11A;
1741 				}
1742 			}
1743 		}
1744 		*pReturnCfgDot11Mode = cfgDot11ModeToUse;
1745 	}
1746 
1747 	return fMatch;
1748 }
1749 
1750 eCsrCfgDot11Mode csr_find_best_phy_mode(tpAniSirGlobal pMac, uint32_t phyMode)
1751 {
1752 	eCsrCfgDot11Mode cfgDot11ModeToUse;
1753 	eCsrBand eBand = pMac->roam.configParam.eBand;
1754 
1755 	if ((0 == phyMode) ||
1756 	    (eCSR_DOT11_MODE_11ac & phyMode) ||
1757 	    (eCSR_DOT11_MODE_AUTO & phyMode)) {
1758 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
1759 			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC;
1760 		} else {
1761 			/* Default to 11N mode if user has configured 11ac mode
1762 			 * and FW doesn't supports 11ac mode .
1763 			 */
1764 			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
1765 		}
1766 	} else {
1767 		if ((eCSR_DOT11_MODE_11n | eCSR_DOT11_MODE_11n_ONLY) & phyMode) {
1768 			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
1769 		} else if (eCSR_DOT11_MODE_abg & phyMode) {
1770 			if (eCSR_BAND_24 != eBand) {
1771 				cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
1772 			} else {
1773 				cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
1774 			}
1775 		} else if (eCSR_DOT11_MODE_11a & phyMode) {
1776 			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
1777 		} else if ((eCSR_DOT11_MODE_11g | eCSR_DOT11_MODE_11g_ONLY) &
1778 			   phyMode) {
1779 			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
1780 		} else {
1781 			cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11B;
1782 		}
1783 	}
1784 
1785 	return cfgDot11ModeToUse;
1786 }
1787 
1788 uint32_t csr_get11h_power_constraint(tHalHandle hHal,
1789 				     tDot11fIEPowerConstraints *pPowerConstraint)
1790 {
1791 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1792 	uint32_t localPowerConstraint = 0;
1793 
1794 	/* check if .11h support is enabled, if not, the power constraint is 0. */
1795 	if (pMac->roam.configParam.Is11hSupportEnabled
1796 	    && pPowerConstraint->present) {
1797 		localPowerConstraint = pPowerConstraint->localPowerConstraints;
1798 	}
1799 
1800 	return localPowerConstraint;
1801 }
1802 
1803 bool csr_is_profile_wpa(tCsrRoamProfile *pProfile)
1804 {
1805 	bool fWpaProfile = false;
1806 
1807 	switch (pProfile->negotiatedAuthType) {
1808 	case eCSR_AUTH_TYPE_WPA:
1809 	case eCSR_AUTH_TYPE_WPA_PSK:
1810 	case eCSR_AUTH_TYPE_WPA_NONE:
1811 #ifdef FEATURE_WLAN_ESE
1812 	case eCSR_AUTH_TYPE_CCKM_WPA:
1813 #endif
1814 		fWpaProfile = true;
1815 		break;
1816 
1817 	default:
1818 		fWpaProfile = false;
1819 		break;
1820 	}
1821 
1822 	if (fWpaProfile) {
1823 		switch (pProfile->negotiatedUCEncryptionType) {
1824 		case eCSR_ENCRYPT_TYPE_WEP40:
1825 		case eCSR_ENCRYPT_TYPE_WEP104:
1826 		case eCSR_ENCRYPT_TYPE_TKIP:
1827 		case eCSR_ENCRYPT_TYPE_AES:
1828 			fWpaProfile = true;
1829 			break;
1830 
1831 		default:
1832 			fWpaProfile = false;
1833 			break;
1834 		}
1835 	}
1836 	return fWpaProfile;
1837 }
1838 
1839 bool csr_is_profile_rsn(tCsrRoamProfile *pProfile)
1840 {
1841 	bool fRSNProfile = false;
1842 
1843 	switch (pProfile->negotiatedAuthType) {
1844 	case eCSR_AUTH_TYPE_RSN:
1845 	case eCSR_AUTH_TYPE_RSN_PSK:
1846 	case eCSR_AUTH_TYPE_FT_RSN:
1847 	case eCSR_AUTH_TYPE_FT_RSN_PSK:
1848 #ifdef FEATURE_WLAN_ESE
1849 	case eCSR_AUTH_TYPE_CCKM_RSN:
1850 #endif
1851 #ifdef WLAN_FEATURE_11W
1852 	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1853 	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1854 #endif
1855 		fRSNProfile = true;
1856 		break;
1857 
1858 	default:
1859 		fRSNProfile = false;
1860 		break;
1861 	}
1862 
1863 	if (fRSNProfile) {
1864 		switch (pProfile->negotiatedUCEncryptionType) {
1865 		/* !!REVIEW - For WPA2, use of RSN IE mandates */
1866 		/* use of AES as encryption. Here, we qualify */
1867 		/* even if encryption type is WEP or TKIP */
1868 		case eCSR_ENCRYPT_TYPE_WEP40:
1869 		case eCSR_ENCRYPT_TYPE_WEP104:
1870 		case eCSR_ENCRYPT_TYPE_TKIP:
1871 		case eCSR_ENCRYPT_TYPE_AES:
1872 			fRSNProfile = true;
1873 			break;
1874 
1875 		default:
1876 			fRSNProfile = false;
1877 			break;
1878 		}
1879 	}
1880 	return fRSNProfile;
1881 }
1882 
1883 /**
1884  * csr_update_mcc_p2p_beacon_interval() - update p2p beacon interval
1885  * @mac_ctx: pointer to mac context
1886  *
1887  * This function is to update the mcc p2p beacon interval
1888  *
1889  * Return: QDF_STATUS
1890  */
1891 static QDF_STATUS csr_update_mcc_p2p_beacon_interval(tpAniSirGlobal mac_ctx)
1892 {
1893 	uint32_t session_id = 0;
1894 	tCsrRoamSession *roam_session;
1895 
1896 	/* If MCC is not supported just break and return SUCCESS */
1897 	if (!mac_ctx->roam.configParam.fenableMCCMode)
1898 		return QDF_STATUS_E_FAILURE;
1899 
1900 	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
1901 		/*
1902 		 * If GO in MCC support different beacon interval,
1903 		 * change the BI of the P2P-GO
1904 		 */
1905 		roam_session = &mac_ctx->roam.roamSession[session_id];
1906 		if (roam_session->bssParams.bssPersona != QDF_P2P_GO_MODE)
1907 			continue;
1908 		/*
1909 		 * Handle different BI scneario based on the
1910 		 * configuration set.If Config is set to 0x02 then
1911 		 * Disconnect all the P2P clients associated. If config
1912 		 * is set to 0x04 then update the BI without
1913 		 * disconnecting all the clients
1914 		 */
1915 		if ((mac_ctx->roam.configParam.fAllowMCCGODiffBI == 0x04)
1916 				&& (roam_session->bssParams.
1917 					updatebeaconInterval)) {
1918 			return csr_send_chng_mcc_beacon_interval(mac_ctx,
1919 					session_id);
1920 		} else if (roam_session->bssParams.updatebeaconInterval) {
1921 			/*
1922 			 * If the configuration of fAllowMCCGODiffBI is set to
1923 			 * other than 0x04
1924 			 */
1925 			return csr_roam_call_callback(mac_ctx,
1926 					session_id,
1927 					NULL, 0,
1928 					eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS,
1929 					eCSR_ROAM_RESULT_NONE);
1930 		}
1931 	}
1932 	return QDF_STATUS_E_FAILURE;
1933 }
1934 
1935 static uint16_t csr_calculate_mcc_beacon_interval(tpAniSirGlobal pMac,
1936 						  uint16_t sta_bi,
1937 						  uint16_t go_gbi)
1938 {
1939 	uint8_t num_beacons = 0;
1940 	uint8_t is_multiple = 0;
1941 	uint16_t go_cbi = 0;
1942 	uint16_t go_fbi = 0;
1943 	uint16_t sta_cbi = 0;
1944 
1945 	/* If GO's given beacon Interval is less than 100 */
1946 	if (go_gbi < 100)
1947 		go_cbi = 100;
1948 	/* if GO's given beacon Interval is greater than or equal to 100 */
1949 	else
1950 		go_cbi = 100 + (go_gbi % 100);
1951 
1952 	if (sta_bi == 0) {
1953 		/* There is possibility to receive zero as value.
1954 		   Which will cause divide by zero. Hence initialise with 100
1955 		 */
1956 		sta_bi = 100;
1957 		sms_log(pMac, LOGW,
1958 			FL("sta_bi 2nd parameter is zero, initialize to %d"),
1959 			sta_bi);
1960 	}
1961 	/* check, if either one is multiple of another */
1962 	if (sta_bi > go_cbi) {
1963 		is_multiple = !(sta_bi % go_cbi);
1964 	} else {
1965 		is_multiple = !(go_cbi % sta_bi);
1966 	}
1967 	/* if it is multiple, then accept GO's beacon interval range [100,199] as it  is */
1968 	if (is_multiple) {
1969 		return go_cbi;
1970 	}
1971 	/* else , if it is not multiple, then then check for number of beacons to be */
1972 	/* inserted based on sta BI */
1973 	num_beacons = sta_bi / 100;
1974 	if (num_beacons) {
1975 		/* GO's final beacon interval will be aligned to sta beacon interval, but */
1976 		/* in the range of [100, 199]. */
1977 		sta_cbi = sta_bi / num_beacons;
1978 		go_fbi = sta_cbi;
1979 	} else {
1980 		/* if STA beacon interval is less than 100, use GO's change bacon interval */
1981 		/* instead of updating to STA's beacon interval. */
1982 		go_fbi = go_cbi;
1983 	}
1984 	return go_fbi;
1985 }
1986 
1987 /**
1988  * csr_validate_p2pcli_bcn_intrvl() - to validate p2pcli beacon interval
1989  * @mac_ctx: pointer to mac context
1990  * @chnl_id: channel id variable
1991  * @bcn_interval: pointer to given beacon interval
1992  * @session_id: given session id
1993  * @status: fill the status in terms of QDF_STATUS to inform caller
1994  *
1995  * This API can provide the validation the beacon interval and re-calculate
1996  * in case concurrency
1997  *
1998  * Return: bool
1999  */
2000 static bool csr_validate_p2pcli_bcn_intrvl(tpAniSirGlobal mac_ctx,
2001 		uint8_t chnl_id, uint16_t *bcn_interval, uint32_t session_id,
2002 		QDF_STATUS *status)
2003 {
2004 	tCsrRoamSession *roamsession;
2005 
2006 	roamsession = &mac_ctx->roam.roamSession[session_id];
2007 	if (roamsession->pCurRoamProfile &&
2008 		(roamsession->pCurRoamProfile->csrPersona ==
2009 			 QDF_STA_MODE)) {
2010 		/* check for P2P client mode */
2011 		sms_log(mac_ctx, LOG1,
2012 			FL(" Ignore Beacon Interval Validation..."));
2013 	} else if (roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE) {
2014 		/* Check for P2P go scenario */
2015 		if ((roamsession->bssParams.operationChn != chnl_id)
2016 			&& (roamsession->bssParams.beaconInterval !=
2017 				*bcn_interval)) {
2018 			sms_log(mac_ctx, LOGE,
2019 				FL("BcnIntrvl is diff can't connect to P2P_GO network ..."));
2020 			*status = QDF_STATUS_E_FAILURE;
2021 			return true;
2022 		}
2023 	}
2024 	return false;
2025 }
2026 
2027 /**
2028  * csr_validate_p2pgo_bcn_intrvl() - to validate p2pgo beacon interval
2029  * @mac_ctx: pointer to mac context
2030  * @chnl_id: channel id variable
2031  * @bcn_interval: pointer to given beacon interval
2032  * @session_id: given session id
2033  * @status: fill the status in terms of QDF_STATUS to inform caller
2034  *
2035  * This API can provide the validation the beacon interval and re-calculate
2036  * in case concurrency
2037  *
2038  * Return: bool
2039  */
2040 static bool csr_validate_p2pgo_bcn_intrvl(tpAniSirGlobal mac_ctx,
2041 		uint8_t chnl_id, uint16_t *bcn_interval,
2042 		uint32_t session_id, QDF_STATUS *status)
2043 {
2044 	tCsrRoamSession *roamsession;
2045 	tCsrConfig *cfg_param;
2046 	tCsrRoamConnectedProfile *conn_profile;
2047 	uint16_t new_bcn_interval;
2048 
2049 	roamsession = &mac_ctx->roam.roamSession[session_id];
2050 	cfg_param = &mac_ctx->roam.configParam;
2051 	conn_profile = &roamsession->connectedProfile;
2052 	if (roamsession->pCurRoamProfile &&
2053 		((roamsession->pCurRoamProfile->csrPersona ==
2054 			  QDF_P2P_CLIENT_MODE) ||
2055 		(roamsession->pCurRoamProfile->csrPersona ==
2056 			  QDF_STA_MODE))) {
2057 		/* check for P2P_client scenario */
2058 		if ((conn_profile->operationChannel == 0) &&
2059 			(conn_profile->beaconInterval == 0))
2060 			return false;
2061 
2062 		if (csr_is_conn_state_connected_infra(mac_ctx, session_id) &&
2063 			(conn_profile->operationChannel != chnl_id) &&
2064 			(conn_profile->beaconInterval != *bcn_interval)) {
2065 			/*
2066 			 * Updated beaconInterval should be used only when
2067 			 * we are starting a new BSS not incase of
2068 			 * client or STA case
2069 			 */
2070 
2071 			/* Calculate beacon Interval for P2P-GO incase of MCC */
2072 			if (cfg_param->conc_custom_rule1 ||
2073 					cfg_param->conc_custom_rule2) {
2074 				new_bcn_interval = CSR_CUSTOM_CONC_GO_BI;
2075 			} else {
2076 				new_bcn_interval =
2077 					csr_calculate_mcc_beacon_interval(
2078 						mac_ctx,
2079 						conn_profile->beaconInterval,
2080 						*bcn_interval);
2081 			}
2082 			if (*bcn_interval != new_bcn_interval)
2083 				*bcn_interval = new_bcn_interval;
2084 			*status = QDF_STATUS_SUCCESS;
2085 			return true;
2086 		}
2087 	}
2088 	return false;
2089 }
2090 
2091 /**
2092  * csr_validate_sta_bcn_intrvl() - to validate sta beacon interval
2093  * @mac_ctx: pointer to mac context
2094  * @chnl_id: channel id variable
2095  * @bcn_interval: pointer to given beacon interval
2096  * @session_id: given session id
2097  * @status: fill the status in terms of QDF_STATUS to inform caller
2098  *
2099  * This API can provide the validation the beacon interval and re-calculate
2100  * in case concurrency
2101  *
2102  * Return: bool
2103  */
2104 static bool csr_validate_sta_bcn_intrvl(tpAniSirGlobal mac_ctx,
2105 			uint8_t chnl_id, uint16_t *bcn_interval,
2106 			uint32_t session_id, QDF_STATUS *status)
2107 {
2108 	tCsrRoamSession *roamsession;
2109 	tCsrConfig *cfg_param;
2110 	uint16_t new_bcn_interval;
2111 
2112 	roamsession = &mac_ctx->roam.roamSession[session_id];
2113 	cfg_param = &mac_ctx->roam.configParam;
2114 
2115 	if (roamsession->pCurRoamProfile &&
2116 		(roamsession->pCurRoamProfile->csrPersona ==
2117 				QDF_P2P_CLIENT_MODE)) {
2118 		/* check for P2P client mode */
2119 		sms_log(mac_ctx, LOG1,
2120 			FL("Bcn Intrvl validation not require for STA/CLIENT"));
2121 		return false;
2122 	}
2123 	if ((roamsession->bssParams.bssPersona == QDF_SAP_MODE) &&
2124 		   (roamsession->bssParams.operationChn != chnl_id)) {
2125 		/*
2126 		 * IF SAP has started and STA wants to connect
2127 		 * on different channel MCC should
2128 		 *  MCC should not be enabled so making it
2129 		 * false to enforce on same channel
2130 		 */
2131 		sms_log(mac_ctx, LOGE,
2132 			FL("*** MCC with SAP+STA sessions ****"));
2133 		*status = QDF_STATUS_SUCCESS;
2134 		return true;
2135 	}
2136 	/*
2137 	 * Check for P2P go scenario
2138 	 * if GO in MCC support different
2139 	 * beacon interval,
2140 	 * change the BI of the P2P-GO
2141 	 */
2142 	if ((roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE) &&
2143 		(roamsession->bssParams.operationChn != chnl_id) &&
2144 		(roamsession->bssParams.beaconInterval != *bcn_interval)) {
2145 		/* if GO in MCC support diff beacon interval, return success */
2146 		if (cfg_param->fAllowMCCGODiffBI == 0x01) {
2147 			*status = QDF_STATUS_SUCCESS;
2148 			return true;
2149 		}
2150 		/*
2151 		 * Send only Broadcast disassoc and update bcn_interval
2152 		 * If configuration is set to 0x04 then dont
2153 		 * disconnect all the station
2154 		 */
2155 		if ((cfg_param->fAllowMCCGODiffBI == 0x02)
2156 			|| (cfg_param->fAllowMCCGODiffBI == 0x04)) {
2157 			/* Check to pass the right beacon Interval */
2158 			if (cfg_param->conc_custom_rule1 ||
2159 				cfg_param->conc_custom_rule2) {
2160 				new_bcn_interval = CSR_CUSTOM_CONC_GO_BI;
2161 			} else {
2162 				new_bcn_interval =
2163 				csr_calculate_mcc_beacon_interval(
2164 					mac_ctx, *bcn_interval,
2165 					roamsession->bssParams.beaconInterval);
2166 			}
2167 			sms_log(mac_ctx, LOG1,
2168 				FL(" Peer AP BI : %d, new Beacon Interval: %d"),
2169 				*bcn_interval, new_bcn_interval);
2170 			/* Update the becon Interval */
2171 			if (new_bcn_interval !=
2172 					roamsession->bssParams.beaconInterval) {
2173 				/* Update the bcn_interval now */
2174 				sms_log(mac_ctx, LOGE,
2175 					FL(" Beacon Interval got changed config used: %d\n"),
2176 					cfg_param->fAllowMCCGODiffBI);
2177 
2178 				roamsession->bssParams.beaconInterval =
2179 					new_bcn_interval;
2180 				roamsession->bssParams.updatebeaconInterval =
2181 					true;
2182 				*status = csr_update_mcc_p2p_beacon_interval(
2183 					mac_ctx);
2184 				return true;
2185 			}
2186 			*status = QDF_STATUS_SUCCESS;
2187 			return true;
2188 		}
2189 		if (cfg_param->fAllowMCCGODiffBI
2190 				== 0x03) {
2191 			/* Disconnect the P2P session */
2192 			roamsession->bssParams.updatebeaconInterval = false;
2193 			*status = csr_roam_call_callback(mac_ctx,
2194 					session_id, NULL, 0,
2195 					eCSR_ROAM_SEND_P2P_STOP_BSS,
2196 					eCSR_ROAM_RESULT_NONE);
2197 			return true;
2198 		}
2199 		sms_log(mac_ctx, LOGE,
2200 			FL("BcnIntrvl is diff can't connect to preferred AP..."));
2201 		*status = QDF_STATUS_E_FAILURE;
2202 		return true;
2203 	}
2204 	return false;
2205 }
2206 
2207 /**
2208  * csr_validate_mcc_beacon_interval() - to validate the mcc beacon interval
2209  * @mac_ctx: pointer to mac context
2210  * @chnl_id: channel number
2211  * @bcn_interval: provided beacon interval
2212  * @cur_session_id: current session id
2213  * @cur_bss_persona: Current BSS persona
2214  *
2215  * This API will validate the mcc beacon interval
2216  *
2217  * Return: QDF_STATUS
2218  */
2219 QDF_STATUS csr_validate_mcc_beacon_interval(tpAniSirGlobal mac_ctx,
2220 					uint8_t chnl_id,
2221 					uint16_t *bcn_interval,
2222 					uint32_t cur_session_id,
2223 					enum tQDF_ADAPTER_MODE cur_bss_persona)
2224 {
2225 	uint32_t session_id = 0;
2226 	QDF_STATUS status;
2227 	bool is_done;
2228 
2229 	/* If MCC is not supported just break */
2230 	if (!mac_ctx->roam.configParam.fenableMCCMode)
2231 		return QDF_STATUS_E_FAILURE;
2232 
2233 	for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
2234 		if (cur_session_id == session_id)
2235 			continue;
2236 
2237 		if (!CSR_IS_SESSION_VALID(mac_ctx, session_id))
2238 			continue;
2239 
2240 		switch (cur_bss_persona) {
2241 		case QDF_STA_MODE:
2242 			is_done = csr_validate_sta_bcn_intrvl(mac_ctx, chnl_id,
2243 					bcn_interval, session_id, &status);
2244 			if (true == is_done)
2245 				return status;
2246 			break;
2247 
2248 		case QDF_P2P_CLIENT_MODE:
2249 			is_done = csr_validate_p2pcli_bcn_intrvl(mac_ctx,
2250 					chnl_id, bcn_interval, session_id,
2251 					&status);
2252 			if (true == is_done)
2253 				return status;
2254 			break;
2255 
2256 		case QDF_SAP_MODE:
2257 		case QDF_IBSS_MODE:
2258 			break;
2259 
2260 		case QDF_P2P_GO_MODE:
2261 			is_done = csr_validate_p2pgo_bcn_intrvl(mac_ctx,
2262 					chnl_id, bcn_interval,
2263 					session_id, &status);
2264 			if (true == is_done)
2265 				return status;
2266 			break;
2267 
2268 		default:
2269 			sms_log(mac_ctx, LOGE,
2270 				FL("Persona not supported : %d"),
2271 				cur_bss_persona);
2272 			return QDF_STATUS_E_FAILURE;
2273 		}
2274 	}
2275 	return QDF_STATUS_SUCCESS;
2276 }
2277 
2278 /**
2279  * csr_is_auth_type11r() - Check if Authentication type is 11R
2280  * @auth_type: The authentication type that is used to make the connection
2281  * @mdie_present: Is MDIE IE present
2282  *
2283  * Return: true if is 11R auth type, false otherwise
2284  */
2285 bool csr_is_auth_type11r(eCsrAuthType auth_type, uint8_t mdie_present)
2286 {
2287 	switch (auth_type) {
2288 	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
2289 		if (mdie_present)
2290 			return true;
2291 		break;
2292 	case eCSR_AUTH_TYPE_FT_RSN_PSK:
2293 	case eCSR_AUTH_TYPE_FT_RSN:
2294 		return true;
2295 		break;
2296 	default:
2297 		break;
2298 	}
2299 	return false;
2300 }
2301 
2302 /* Function to return true if the profile is 11r */
2303 bool csr_is_profile11r(tCsrRoamProfile *pProfile)
2304 {
2305 	return csr_is_auth_type11r(pProfile->negotiatedAuthType,
2306 				   pProfile->MDID.mdiePresent);
2307 }
2308 
2309 
2310 #ifdef FEATURE_WLAN_ESE
2311 
2312 /* Function to return true if the authtype is ESE */
2313 bool csr_is_auth_type_ese(eCsrAuthType AuthType)
2314 {
2315 	switch (AuthType) {
2316 	case eCSR_AUTH_TYPE_CCKM_WPA:
2317 	case eCSR_AUTH_TYPE_CCKM_RSN:
2318 		return true;
2319 		break;
2320 	default:
2321 		break;
2322 	}
2323 	return false;
2324 }
2325 
2326 /* Function to return true if the profile is ESE */
2327 bool csr_is_profile_ese(tCsrRoamProfile *pProfile)
2328 {
2329 	return csr_is_auth_type_ese(pProfile->negotiatedAuthType);
2330 }
2331 
2332 #endif
2333 
2334 #ifdef FEATURE_WLAN_WAPI
2335 bool csr_is_profile_wapi(tCsrRoamProfile *pProfile)
2336 {
2337 	bool fWapiProfile = false;
2338 
2339 	switch (pProfile->negotiatedAuthType) {
2340 	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
2341 	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
2342 		fWapiProfile = true;
2343 		break;
2344 
2345 	default:
2346 		fWapiProfile = false;
2347 		break;
2348 	}
2349 
2350 	if (fWapiProfile) {
2351 		switch (pProfile->negotiatedUCEncryptionType) {
2352 		case eCSR_ENCRYPT_TYPE_WPI:
2353 			fWapiProfile = true;
2354 			break;
2355 
2356 		default:
2357 			fWapiProfile = false;
2358 			break;
2359 		}
2360 	}
2361 	return fWapiProfile;
2362 }
2363 
2364 static bool csr_is_wapi_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1,
2365 				  uint8_t *Oui2)
2366 {
2367 	return !qdf_mem_cmp(Oui1, Oui2, CSR_WAPI_OUI_SIZE);
2368 }
2369 
2370 static bool csr_is_wapi_oui_match(tpAniSirGlobal pMac,
2371 				  uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE],
2372 				  uint8_t cAllCyphers, uint8_t Cypher[],
2373 				  uint8_t Oui[])
2374 {
2375 	bool fYes = false;
2376 	uint8_t idx;
2377 
2378 	for (idx = 0; idx < cAllCyphers; idx++) {
2379 		if (csr_is_wapi_oui_equal(pMac, AllCyphers[idx], Cypher)) {
2380 			fYes = true;
2381 			break;
2382 		}
2383 	}
2384 
2385 	if (fYes && Oui) {
2386 		qdf_mem_copy(Oui, AllCyphers[idx], CSR_WAPI_OUI_SIZE);
2387 	}
2388 
2389 	return fYes;
2390 }
2391 #endif /* FEATURE_WLAN_WAPI */
2392 
2393 static bool csr_is_wpa_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1,
2394 				 uint8_t *Oui2)
2395 {
2396 	return !qdf_mem_cmp(Oui1, Oui2, CSR_WPA_OUI_SIZE);
2397 }
2398 
2399 static bool csr_is_oui_match(tpAniSirGlobal pMac,
2400 			     uint8_t AllCyphers[][CSR_WPA_OUI_SIZE],
2401 			     uint8_t cAllCyphers, uint8_t Cypher[], uint8_t Oui[])
2402 {
2403 	bool fYes = false;
2404 	uint8_t idx;
2405 
2406 	for (idx = 0; idx < cAllCyphers; idx++) {
2407 		if (csr_is_wpa_oui_equal(pMac, AllCyphers[idx], Cypher)) {
2408 			fYes = true;
2409 			break;
2410 		}
2411 	}
2412 
2413 	if (fYes && Oui) {
2414 		qdf_mem_copy(Oui, AllCyphers[idx], CSR_WPA_OUI_SIZE);
2415 	}
2416 
2417 	return fYes;
2418 }
2419 
2420 static bool csr_match_rsnoui_index(tpAniSirGlobal pMac,
2421 				   uint8_t AllCyphers[][CSR_RSN_OUI_SIZE],
2422 				   uint8_t cAllCyphers, uint8_t ouiIndex,
2423 				   uint8_t Oui[])
2424 {
2425 	return csr_is_oui_match
2426 		(pMac, AllCyphers, cAllCyphers, csr_rsn_oui[ouiIndex], Oui);
2427 
2428 }
2429 
2430 #ifdef FEATURE_WLAN_WAPI
2431 static bool csr_match_wapi_oui_index(tpAniSirGlobal pMac,
2432 				     uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE],
2433 				     uint8_t cAllCyphers, uint8_t ouiIndex,
2434 				     uint8_t Oui[])
2435 {
2436 	return csr_is_wapi_oui_match
2437 		(pMac, AllCyphers, cAllCyphers, csr_wapi_oui[ouiIndex], Oui);
2438 
2439 }
2440 #endif /* FEATURE_WLAN_WAPI */
2441 
2442 static bool csr_match_wpaoui_index(tpAniSirGlobal pMac,
2443 				   uint8_t AllCyphers[][CSR_RSN_OUI_SIZE],
2444 				   uint8_t cAllCyphers, uint8_t ouiIndex,
2445 				   uint8_t Oui[])
2446 {
2447 	return csr_is_oui_match
2448 		(pMac, AllCyphers, cAllCyphers, csr_wpa_oui[ouiIndex], Oui);
2449 
2450 }
2451 
2452 #ifdef FEATURE_WLAN_WAPI
2453 static bool csr_is_auth_wapi_cert(tpAniSirGlobal pMac,
2454 				  uint8_t AllSuites[][CSR_WAPI_OUI_SIZE],
2455 				  uint8_t cAllSuites, uint8_t Oui[])
2456 {
2457 	return csr_is_wapi_oui_match
2458 		(pMac, AllSuites, cAllSuites, csr_wapi_oui[1], Oui);
2459 }
2460 
2461 static bool csr_is_auth_wapi_psk(tpAniSirGlobal pMac,
2462 				 uint8_t AllSuites[][CSR_WAPI_OUI_SIZE],
2463 				 uint8_t cAllSuites, uint8_t Oui[])
2464 {
2465 	return csr_is_wapi_oui_match
2466 		(pMac, AllSuites, cAllSuites, csr_wapi_oui[2], Oui);
2467 }
2468 #endif /* FEATURE_WLAN_WAPI */
2469 
2470 
2471 /*
2472  * Function for 11R FT Authentication. We match the FT Authentication Cipher
2473  * suite here. This matches for FT Auth with the 802.1X exchange.
2474  */
2475 static bool csr_is_ft_auth_rsn(tpAniSirGlobal pMac,
2476 			       uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2477 			       uint8_t cAllSuites, uint8_t Oui[])
2478 {
2479 	return csr_is_oui_match
2480 		(pMac, AllSuites, cAllSuites, csr_rsn_oui[03], Oui);
2481 }
2482 
2483 /*
2484  * Function for 11R FT Authentication. We match the FT Authentication Cipher
2485  * suite here. This matches for FT Auth with the PSK.
2486  */
2487 static bool csr_is_ft_auth_rsn_psk(tpAniSirGlobal pMac,
2488 				   uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2489 				   uint8_t cAllSuites, uint8_t Oui[])
2490 {
2491 	return csr_is_oui_match
2492 		(pMac, AllSuites, cAllSuites, csr_rsn_oui[04], Oui);
2493 }
2494 
2495 
2496 #ifdef FEATURE_WLAN_ESE
2497 
2498 /*
2499  * Function for ESE CCKM AKM Authentication. We match the CCKM AKM
2500  * Authentication Key Management suite here. This matches for CCKM AKM Auth
2501  * with the 802.1X exchange.
2502  */
2503 static bool csr_is_ese_cckm_auth_rsn(tpAniSirGlobal pMac,
2504 				     uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2505 				     uint8_t cAllSuites, uint8_t Oui[])
2506 {
2507 	return csr_is_oui_match
2508 		(pMac, AllSuites, cAllSuites, csr_rsn_oui[06], Oui);
2509 }
2510 
2511 static bool csr_is_ese_cckm_auth_wpa(tpAniSirGlobal pMac,
2512 				     uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
2513 				     uint8_t cAllSuites, uint8_t Oui[])
2514 {
2515 	return csr_is_oui_match
2516 		(pMac, AllSuites, cAllSuites, csr_wpa_oui[06], Oui);
2517 }
2518 
2519 #endif
2520 
2521 static bool csr_is_auth_rsn(tpAniSirGlobal pMac,
2522 			    uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2523 			    uint8_t cAllSuites, uint8_t Oui[])
2524 {
2525 	return csr_is_oui_match
2526 		(pMac, AllSuites, cAllSuites, csr_rsn_oui[01], Oui);
2527 }
2528 
2529 static bool csr_is_auth_rsn_psk(tpAniSirGlobal pMac,
2530 				uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2531 				uint8_t cAllSuites, uint8_t Oui[])
2532 {
2533 	return csr_is_oui_match
2534 		(pMac, AllSuites, cAllSuites, csr_rsn_oui[02], Oui);
2535 }
2536 
2537 #ifdef WLAN_FEATURE_11W
2538 static bool csr_is_auth_rsn_psk_sha256(tpAniSirGlobal pMac,
2539 				       uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2540 				       uint8_t cAllSuites, uint8_t Oui[])
2541 {
2542 	return csr_is_oui_match
2543 		(pMac, AllSuites, cAllSuites, csr_rsn_oui[07], Oui);
2544 }
2545 static bool csr_is_auth_rsn8021x_sha256(tpAniSirGlobal pMac,
2546 					uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2547 					uint8_t cAllSuites, uint8_t Oui[])
2548 {
2549 	return csr_is_oui_match
2550 		(pMac, AllSuites, cAllSuites, csr_rsn_oui[8], Oui);
2551 }
2552 #endif
2553 
2554 static bool csr_is_auth_wpa(tpAniSirGlobal pMac,
2555 			    uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
2556 			    uint8_t cAllSuites, uint8_t Oui[])
2557 {
2558 	return csr_is_oui_match
2559 		(pMac, AllSuites, cAllSuites, csr_wpa_oui[01], Oui);
2560 }
2561 
2562 static bool csr_is_auth_wpa_psk(tpAniSirGlobal pMac,
2563 				uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
2564 				uint8_t cAllSuites, uint8_t Oui[])
2565 {
2566 	return csr_is_oui_match
2567 		(pMac, AllSuites, cAllSuites, csr_wpa_oui[02], Oui);
2568 }
2569 
2570 static uint8_t csr_get_oui_index_from_cipher(eCsrEncryptionType enType)
2571 {
2572 	uint8_t OUIIndex;
2573 
2574 	switch (enType) {
2575 	case eCSR_ENCRYPT_TYPE_WEP40:
2576 	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
2577 		OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX;
2578 		break;
2579 	case eCSR_ENCRYPT_TYPE_WEP104:
2580 	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
2581 		OUIIndex = CSR_OUI_WEP104_INDEX;
2582 		break;
2583 	case eCSR_ENCRYPT_TYPE_TKIP:
2584 		OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX;
2585 		break;
2586 	case eCSR_ENCRYPT_TYPE_AES:
2587 		OUIIndex = CSR_OUI_AES_INDEX;
2588 		break;
2589 	case eCSR_ENCRYPT_TYPE_NONE:
2590 		OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX;
2591 		break;
2592 #ifdef FEATURE_WLAN_WAPI
2593 	case eCSR_ENCRYPT_TYPE_WPI:
2594 		OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX;
2595 		break;
2596 #endif /* FEATURE_WLAN_WAPI */
2597 	default:                /* HOWTO handle this? */
2598 		OUIIndex = CSR_OUI_RESERVED_INDEX;
2599 		break;
2600 	} /* switch */
2601 
2602 	return OUIIndex;
2603 }
2604 /**
2605  * csr_get_rsn_information() - to get RSN infomation
2606  * @hal: pointer to HAL
2607  * @auth_type: auth type
2608  * @encr_type: encryption type
2609  * @mc_encryption: multicast encryption type
2610  * @rsn_ie: pointer to RSN IE
2611  * @ucast_cipher: Unicast cipher
2612  * @mcast_cipher: Multicast cipher
2613  * @auth_suite: Authentication suite
2614  * @capabilities: RSN capabilities
2615  * @negotiated_authtype: Negotiated auth type
2616  * @negotiated_mccipher: negotiated multicast cipher
2617  *
2618  * This routine will get all RSN information
2619  *
2620  * Return: bool
2621  */
2622 static bool csr_get_rsn_information(tHalHandle hal, tCsrAuthList *auth_type,
2623 				    eCsrEncryptionType encr_type,
2624 				    tCsrEncryptionList *mc_encryption,
2625 				    tDot11fIERSN *rsn_ie, uint8_t *ucast_cipher,
2626 				    uint8_t *mcast_cipher, uint8_t *auth_suite,
2627 				    tCsrRSNCapabilities *capabilities,
2628 				    eCsrAuthType *negotiated_authtype,
2629 				    eCsrEncryptionType *negotiated_mccipher)
2630 {
2631 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
2632 	bool acceptable_cipher = false;
2633 	uint8_t c_ucast_cipher = 0;
2634 	uint8_t c_mcast_cipher = 0;
2635 	uint8_t c_auth_suites = 0, i;
2636 	uint8_t unicast[CSR_RSN_OUI_SIZE];
2637 	uint8_t multicast[CSR_RSN_OUI_SIZE];
2638 	uint8_t authsuites[CSR_RSN_MAX_AUTH_SUITES][CSR_RSN_OUI_SIZE];
2639 	uint8_t authentication[CSR_RSN_OUI_SIZE];
2640 	uint8_t mccipher_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
2641 	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
2642 
2643 	if (!rsn_ie->present)
2644 		goto end;
2645 	c_mcast_cipher++;
2646 	qdf_mem_copy(mccipher_arr, rsn_ie->gp_cipher_suite,
2647 			CSR_RSN_OUI_SIZE);
2648 	c_ucast_cipher =
2649 		(uint8_t) (rsn_ie->pwise_cipher_suite_count);
2650 	c_auth_suites = (uint8_t) (rsn_ie->akm_suite_count);
2651 	for (i = 0; i < c_auth_suites && i < CSR_RSN_MAX_AUTH_SUITES; i++) {
2652 		qdf_mem_copy((void *)&authsuites[i],
2653 			(void *)&rsn_ie->akm_suites[i], CSR_RSN_OUI_SIZE);
2654 	}
2655 
2656 	/* Check - Is requested unicast Cipher supported by the BSS. */
2657 	acceptable_cipher = csr_match_rsnoui_index(mac_ctx,
2658 				rsn_ie->pwise_cipher_suites, c_ucast_cipher,
2659 				csr_get_oui_index_from_cipher(encr_type),
2660 				unicast);
2661 
2662 	if (!acceptable_cipher)
2663 		goto end;
2664 
2665 	/* unicast is supported. Pick the first matching Group cipher, if any */
2666 	for (i = 0; i < mc_encryption->numEntries; i++) {
2667 		acceptable_cipher = csr_match_rsnoui_index(mac_ctx,
2668 					mccipher_arr, c_mcast_cipher,
2669 					csr_get_oui_index_from_cipher(
2670 					    mc_encryption->encryptionType[i]),
2671 					multicast);
2672 		if (acceptable_cipher)
2673 			break;
2674 	}
2675 	if (!acceptable_cipher)
2676 		goto end;
2677 
2678 	if (negotiated_mccipher)
2679 		*negotiated_mccipher = mc_encryption->encryptionType[i];
2680 
2681 	/* Initializing with false as it has true value already */
2682 	acceptable_cipher = false;
2683 	for (i = 0; i < auth_type->numEntries; i++) {
2684 		/*
2685 		 * Ciphers are supported, Match authentication algorithm and
2686 		 * pick first matching authtype.
2687 		 */
2688 		/* Changed the AKM suites according to order of preference */
2689 		if (csr_is_ft_auth_rsn(mac_ctx, authsuites,
2690 					c_auth_suites, authentication)) {
2691 			if (eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i])
2692 				neg_authtype = eCSR_AUTH_TYPE_FT_RSN;
2693 		}
2694 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
2695 				&& csr_is_ft_auth_rsn_psk(mac_ctx, authsuites,
2696 					c_auth_suites, authentication)) {
2697 			if (eCSR_AUTH_TYPE_FT_RSN_PSK ==
2698 					auth_type->authType[i])
2699 				neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK;
2700 		}
2701 #ifdef FEATURE_WLAN_ESE
2702 		/* ESE only supports 802.1X.  No PSK. */
2703 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
2704 				csr_is_ese_cckm_auth_rsn(mac_ctx, authsuites,
2705 					c_auth_suites, authentication)) {
2706 			if (eCSR_AUTH_TYPE_CCKM_RSN == auth_type->authType[i])
2707 				neg_authtype = eCSR_AUTH_TYPE_CCKM_RSN;
2708 		}
2709 #endif
2710 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
2711 				&& csr_is_auth_rsn(mac_ctx, authsuites,
2712 					c_auth_suites, authentication)) {
2713 			if (eCSR_AUTH_TYPE_RSN == auth_type->authType[i])
2714 				neg_authtype = eCSR_AUTH_TYPE_RSN;
2715 		}
2716 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
2717 				&& csr_is_auth_rsn_psk(mac_ctx, authsuites,
2718 					c_auth_suites, authentication)) {
2719 			if (eCSR_AUTH_TYPE_RSN_PSK == auth_type->authType[i])
2720 				neg_authtype = eCSR_AUTH_TYPE_RSN_PSK;
2721 		}
2722 #ifdef WLAN_FEATURE_11W
2723 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
2724 			&& csr_is_auth_rsn_psk_sha256(mac_ctx, authsuites,
2725 					c_auth_suites, authentication)) {
2726 			if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 ==
2727 					auth_type->authType[i])
2728 				neg_authtype = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
2729 		}
2730 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
2731 				csr_is_auth_rsn8021x_sha256(mac_ctx, authsuites,
2732 					c_auth_suites, authentication)) {
2733 			if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
2734 					auth_type->authType[i])
2735 				neg_authtype = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
2736 		}
2737 #endif
2738 
2739 		/*
2740 		 * The 1st auth type in the APs RSN IE, to match stations
2741 		 * connecting profiles auth type will cause us to exit this
2742 		 * loop. This is added as some APs advertise multiple akms in
2743 		 * the RSN IE
2744 		 */
2745 		if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) {
2746 			acceptable_cipher = true;
2747 			break;
2748 		}
2749 	} /* for */
2750 end:
2751 	if (acceptable_cipher) {
2752 		if (mcast_cipher)
2753 			qdf_mem_copy(mcast_cipher, multicast,
2754 					CSR_RSN_OUI_SIZE);
2755 
2756 		if (ucast_cipher)
2757 			qdf_mem_copy(ucast_cipher, unicast, CSR_RSN_OUI_SIZE);
2758 
2759 		if (auth_suite)
2760 			qdf_mem_copy(auth_suite, authentication,
2761 					CSR_RSN_OUI_SIZE);
2762 
2763 		if (negotiated_authtype)
2764 			*negotiated_authtype = neg_authtype;
2765 
2766 		if (capabilities) {
2767 			/* Bit 0 Preauthentication */
2768 			capabilities->PreAuthSupported =
2769 				(rsn_ie->RSN_Cap[0] >> 0) & 0x1;
2770 			/* Bit 1 No Pairwise */
2771 			capabilities->NoPairwise =
2772 				(rsn_ie->RSN_Cap[0] >> 1) & 0x1;
2773 			/* Bit 2, 3 PTKSA Replay Counter */
2774 			capabilities->PTKSAReplayCounter =
2775 				(rsn_ie->RSN_Cap[0] >> 2) & 0x3;
2776 			/* Bit 4, 5 GTKSA Replay Counter */
2777 			capabilities->GTKSAReplayCounter =
2778 				(rsn_ie->RSN_Cap[0] >> 4) & 0x3;
2779 #ifdef WLAN_FEATURE_11W
2780 			/* Bit 6 MFPR */
2781 			capabilities->MFPRequired =
2782 				(rsn_ie->RSN_Cap[0] >> 6) & 0x1;
2783 			/* Bit 7 MFPC */
2784 			capabilities->MFPCapable =
2785 				(rsn_ie->RSN_Cap[0] >> 7) & 0x1;
2786 #else
2787 			/* Bit 6 MFPR */
2788 			capabilities->MFPRequired = 0;
2789 			/* Bit 7 MFPC */
2790 			capabilities->MFPCapable = 0;
2791 #endif
2792 			/* remaining reserved */
2793 			capabilities->Reserved = rsn_ie->RSN_Cap[1] & 0xff;
2794 		}
2795 	}
2796 	return acceptable_cipher;
2797 }
2798 
2799 #ifdef WLAN_FEATURE_11W
2800 /**
2801  * csr_is_pmf_capabilities_in_rsn_match() - check for PMF capability
2802  * @hHal:                  Global HAL handle
2803  * @pFilterMFPEnabled:     given by supplicant to us to specify what kind
2804  *                         of connection supplicant is expecting to make
2805  *                         if it is enabled then make PMF connection.
2806  *                         if it is disabled then make normal connection.
2807  * @pFilterMFPRequired:    given by supplicant based on our configuration
2808  *                         if it is 1 then we will require mandatory
2809  *                         PMF connection and if it is 0 then we PMF
2810  *                         connection is optional.
2811  * @pFilterMFPCapable:     given by supplicant based on our configuration
2812  *                         if it 1 then we are PMF capable and if it 0
2813  *                         then we are not PMF capable.
2814  * @pRSNIe:                RSNIe from Beacon/probe response of
2815  *                         neighbor AP against which we will compare
2816  *                         our capabilities.
2817  *
2818  * This function is to match our current capabilities with the AP
2819  * to which we are expecting make the connection.
2820  *
2821  * Return:   if our PMF capabilities matches with AP then we
2822  *           will return true to indicate that we are good
2823  *           to make connection with it. Else we will return false
2824  **/
2825 static bool
2826 csr_is_pmf_capabilities_in_rsn_match(tHalHandle hHal,
2827 				     bool *pFilterMFPEnabled,
2828 				     uint8_t *pFilterMFPRequired,
2829 				     uint8_t *pFilterMFPCapable,
2830 				     tDot11fIERSN *pRSNIe)
2831 {
2832 	uint8_t apProfileMFPCapable = 0;
2833 	uint8_t apProfileMFPRequired = 0;
2834 	if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable
2835 	    && pFilterMFPRequired) {
2836 		/* Extracting MFPCapable bit from RSN Ie */
2837 		apProfileMFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1;
2838 		apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1;
2839 
2840 		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
2841 			FL("pFilterMFPEnabled=%d pFilterMFPRequired=%d"
2842 			   "pFilterMFPCapable=%d apProfileMFPCapable=%d"
2843 			   "apProfileMFPRequired=%d"),
2844 			 *pFilterMFPEnabled, *pFilterMFPRequired,
2845 			 *pFilterMFPCapable, apProfileMFPCapable,
2846 			 apProfileMFPRequired);
2847 
2848 		if (*pFilterMFPEnabled && *pFilterMFPCapable
2849 		    && *pFilterMFPRequired && (apProfileMFPCapable == 0)) {
2850 			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
2851 				  "AP is not capable to make PMF connection");
2852 			return false;
2853 		}  else if (!(*pFilterMFPCapable) &&
2854 			   apProfileMFPCapable && apProfileMFPRequired) {
2855 
2856 			/*
2857 			 * In this case, AP with whom we trying to connect
2858 			 * requires mandatory PMF connections and we are not
2859 			 * capable so this AP is not good choice to connect
2860 			 */
2861 			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
2862 				  "AP needs PMF connection and we are not capable of pmf connection");
2863 			return false;
2864 		}
2865 	}
2866 	return true;
2867 }
2868 #endif
2869 
2870 static bool csr_is_rsn_match(tHalHandle hHal, tCsrAuthList *pAuthType,
2871 			     eCsrEncryptionType enType,
2872 			     tCsrEncryptionList *pEnMcType,
2873 			     bool *pMFPEnabled, uint8_t *pMFPRequired,
2874 			     uint8_t *pMFPCapable,
2875 			     tDot11fBeaconIEs *pIes,
2876 			     eCsrAuthType *pNegotiatedAuthType,
2877 			     eCsrEncryptionType *pNegotiatedMCCipher)
2878 {
2879 	bool fRSNMatch = false;
2880 
2881 	/* See if the cyphers in the Bss description match with the settings in the profile. */
2882 	fRSNMatch =
2883 		csr_get_rsn_information(hHal, pAuthType, enType, pEnMcType, &pIes->RSN,
2884 					NULL, NULL, NULL, NULL, pNegotiatedAuthType,
2885 					pNegotiatedMCCipher);
2886 #ifdef WLAN_FEATURE_11W
2887 	/* If all the filter matches then finally checks for PMF capabilities */
2888 	if (fRSNMatch) {
2889 		fRSNMatch = csr_is_pmf_capabilities_in_rsn_match(hHal, pMFPEnabled,
2890 								 pMFPRequired,
2891 								 pMFPCapable,
2892 								 &pIes->RSN);
2893 	}
2894 #endif
2895 	return fRSNMatch;
2896 }
2897 
2898 static bool csr_lookup_pmkid(tpAniSirGlobal pMac, uint32_t sessionId,
2899 			     uint8_t *pBSSId, uint8_t *pPMKId)
2900 {
2901 	bool fRC = false, fMatchFound = false;
2902 	uint32_t Index;
2903 	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
2904 
2905 	if (!pSession) {
2906 		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
2907 		return false;
2908 	}
2909 
2910 	do {
2911 		for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
2912 			sms_log(pMac, LOG1,
2913 				"match PMKID " MAC_ADDRESS_STR " to ",
2914 				MAC_ADDR_ARRAY(pBSSId));
2915 			if (!qdf_mem_cmp
2916 			    (pBSSId, pSession->PmkidCacheInfo[Index].BSSID.bytes,
2917 			    sizeof(struct qdf_mac_addr))) {
2918 				/* match found */
2919 				fMatchFound = true;
2920 				break;
2921 			}
2922 		}
2923 
2924 		if (!fMatchFound)
2925 			break;
2926 
2927 		qdf_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID,
2928 			     CSR_RSN_PMKID_SIZE);
2929 
2930 		fRC = true;
2931 	} while (0);
2932 	sms_log(pMac, LOGW,
2933 		"csr_lookup_pmkid called return match = %d pMac->roam.NumPmkidCache = %d",
2934 		fRC, pSession->NumPmkidCache);
2935 
2936 	return fRC;
2937 }
2938 
2939 uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId,
2940 			     tCsrRoamProfile *pProfile,
2941 			     tSirBssDescription *pSirBssDesc,
2942 			     tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe)
2943 {
2944 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2945 	bool fRSNMatch;
2946 	uint8_t cbRSNIe = 0;
2947 	uint8_t UnicastCypher[CSR_RSN_OUI_SIZE];
2948 	uint8_t MulticastCypher[CSR_RSN_OUI_SIZE];
2949 	uint8_t AuthSuite[CSR_RSN_OUI_SIZE];
2950 	tCsrRSNAuthIe *pAuthSuite;
2951 	tCsrRSNCapabilities RSNCapabilities;
2952 	tCsrRSNPMKIe *pPMK;
2953 	uint8_t PMKId[CSR_RSN_PMKID_SIZE];
2954 #ifdef WLAN_FEATURE_11W
2955 	uint8_t *pGroupMgmtCipherSuite;
2956 #endif
2957 	tDot11fBeaconIEs *pIesLocal = pIes;
2958 	eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;
2959 
2960 	sms_log(pMac, LOGW, "%s called...", __func__);
2961 
2962 	do {
2963 		if (!csr_is_profile_rsn(pProfile))
2964 			break;
2965 
2966 		if (!pIesLocal
2967 		    &&
2968 		    (!QDF_IS_STATUS_SUCCESS
2969 			     (csr_get_parsed_bss_description_ies
2970 				     (pMac, pSirBssDesc, &pIesLocal)))) {
2971 			break;
2972 		}
2973 		/* See if the cyphers in the Bss description match with the settings in the profile. */
2974 		fRSNMatch =
2975 			csr_get_rsn_information(hHal, &pProfile->AuthType,
2976 						pProfile->negotiatedUCEncryptionType,
2977 						&pProfile->mcEncryptionType,
2978 						&pIesLocal->RSN, UnicastCypher,
2979 						MulticastCypher, AuthSuite,
2980 						&RSNCapabilities, &negAuthType, NULL);
2981 		if (!fRSNMatch)
2982 			break;
2983 
2984 		pRSNIe->IeHeader.ElementID = SIR_MAC_RSN_EID;
2985 
2986 		pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED;
2987 
2988 		qdf_mem_copy(pRSNIe->MulticastOui, MulticastCypher,
2989 			     sizeof(MulticastCypher));
2990 
2991 		pRSNIe->cUnicastCyphers = 1;
2992 
2993 		qdf_mem_copy(&pRSNIe->UnicastOui[0], UnicastCypher,
2994 			     sizeof(UnicastCypher));
2995 
2996 		pAuthSuite =
2997 			(tCsrRSNAuthIe *) (&pRSNIe->
2998 					   UnicastOui[pRSNIe->cUnicastCyphers]);
2999 
3000 		pAuthSuite->cAuthenticationSuites = 1;
3001 		qdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite,
3002 			     sizeof(AuthSuite));
3003 
3004 		/* RSN capabilities follows the Auth Suite (two octects) */
3005 		/* !!REVIEW - What should STA put in RSN capabilities, currently */
3006 		/* just putting back APs capabilities */
3007 		/* For one, we shouldn't EVER be sending out "pre-auth supported".  It is an AP only capability */
3008 		/* For another, we should use the Management Frame Protection values given by the supplicant */
3009 		RSNCapabilities.PreAuthSupported = 0;
3010 #ifdef WLAN_FEATURE_11W
3011 		if (RSNCapabilities.MFPCapable && pProfile->MFPCapable) {
3012 			RSNCapabilities.MFPCapable = pProfile->MFPCapable;
3013 			RSNCapabilities.MFPRequired = pProfile->MFPRequired;
3014 		} else {
3015 			RSNCapabilities.MFPCapable = 0;
3016 			RSNCapabilities.MFPRequired = 0;
3017 		}
3018 #endif
3019 		*(uint16_t *) (&pAuthSuite->AuthOui[1]) =
3020 			*((uint16_t *) (&RSNCapabilities));
3021 
3022 		pPMK =
3023 			(tCsrRSNPMKIe *) (((uint8_t *) (&pAuthSuite->AuthOui[1])) +
3024 					  sizeof(uint16_t));
3025 
3026 		/* Don't include the PMK SA IDs for CCKM associations. */
3027 		if (
3028 #ifdef FEATURE_WLAN_ESE
3029 			(eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) &&
3030 #endif
3031 			csr_lookup_pmkid(pMac, sessionId, pSirBssDesc->bssId,
3032 					 &(PMKId[0]))) {
3033 			pPMK->cPMKIDs = 1;
3034 
3035 			qdf_mem_copy(pPMK->PMKIDList[0].PMKID, PMKId,
3036 				     CSR_RSN_PMKID_SIZE);
3037 		} else {
3038 			pPMK->cPMKIDs = 0;
3039 		}
3040 
3041 #ifdef WLAN_FEATURE_11W
3042 		/* Advertise BIP in group cipher key management only if PMF is
3043 		 * enabled and AP is capable.
3044 		 */
3045 		if (pProfile->MFPEnabled &&
3046 			(RSNCapabilities.MFPCapable && pProfile->MFPCapable)) {
3047 			pGroupMgmtCipherSuite =
3048 				(uint8_t *) pPMK + sizeof(uint16_t) +
3049 				(pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE);
3050 			qdf_mem_copy(pGroupMgmtCipherSuite, csr_rsn_oui[07],
3051 				     CSR_WPA_OUI_SIZE);
3052 		}
3053 #endif
3054 
3055 		/* Add in the fixed fields plus 1 Unicast cypher, less the IE Header length */
3056 		/* Add in the size of the Auth suite (count plus a single OUI) */
3057 		/* Add in the RSN caps field. */
3058 		/* Add PMKID count and PMKID (if any) */
3059 		/* Add group management cipher suite */
3060 		pRSNIe->IeHeader.Length =
3061 			(uint8_t) (sizeof(*pRSNIe) - sizeof(pRSNIe->IeHeader) +
3062 				   sizeof(*pAuthSuite) +
3063 				   sizeof(tCsrRSNCapabilities));
3064 		if (pPMK->cPMKIDs) {
3065 			pRSNIe->IeHeader.Length += (uint8_t) (sizeof(uint16_t) +
3066 							      (pPMK->cPMKIDs *
3067 							       CSR_RSN_PMKID_SIZE));
3068 		}
3069 #ifdef WLAN_FEATURE_11W
3070 		if (pProfile->MFPEnabled &&
3071 			(RSNCapabilities.MFPCapable && pProfile->MFPCapable)) {
3072 			if (0 == pPMK->cPMKIDs)
3073 				pRSNIe->IeHeader.Length += sizeof(uint16_t);
3074 			pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE;
3075 		}
3076 #endif
3077 
3078 		/* return the size of the IE header (total) constructed... */
3079 		cbRSNIe = pRSNIe->IeHeader.Length + sizeof(pRSNIe->IeHeader);
3080 
3081 	} while (0);
3082 
3083 	if (!pIes && pIesLocal) {
3084 		/* locally allocated */
3085 		qdf_mem_free(pIesLocal);
3086 	}
3087 
3088 	return cbRSNIe;
3089 }
3090 
3091 #ifdef FEATURE_WLAN_WAPI
3092 /**
3093  * csr_get_wapi_information() - to get WAPI infomation
3094  * @hal: pointer to HAL
3095  * @auth_type: auth type
3096  * @encr_type: encryption type
3097  * @mc_encryption: multicast encryption type
3098  * @wapi_ie: pointer to WAPI IE
3099  * @ucast_cipher: Unicast cipher
3100  * @mcast_cipher: Multicast cipher
3101  * @auth_suite: Authentication suite
3102  * @negotiated_authtype: Negotiated auth type
3103  * @negotiated_mccipher: negotiated multicast cipher
3104  *
3105  * This routine will get all WAPI information
3106  *
3107  * Return: bool
3108  */
3109 static bool csr_get_wapi_information(tHalHandle hal, tCsrAuthList *auth_type,
3110 				     eCsrEncryptionType encr_type,
3111 				     tCsrEncryptionList *mc_encryption,
3112 				     tDot11fIEWAPI *wapi_ie,
3113 				     uint8_t *ucast_cipher,
3114 				     uint8_t *mcast_cipher, uint8_t *auth_suite,
3115 				     eCsrAuthType *negotiated_authtype,
3116 				     eCsrEncryptionType *negotiated_mccipher)
3117 {
3118 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
3119 	bool acceptable_cipher = false;
3120 	uint8_t c_ucast_cipher = 0;
3121 	uint8_t c_mcast_cipher = 0;
3122 	uint8_t c_auth_suites = 0, i;
3123 	uint8_t unicast[CSR_WAPI_OUI_SIZE];
3124 	uint8_t multicast[CSR_WAPI_OUI_SIZE];
3125 	uint8_t authsuites[CSR_WAPI_MAX_AUTH_SUITES][CSR_WAPI_OUI_SIZE];
3126 	uint8_t authentication[CSR_WAPI_OUI_SIZE];
3127 	uint8_t mccipher_arr[CSR_WAPI_MAX_MULTICAST_CYPHERS][CSR_WAPI_OUI_SIZE];
3128 	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
3129 	uint8_t wapioui_idx = 0;
3130 
3131 	if (!wapi_ie->present)
3132 		goto end;
3133 
3134 	c_mcast_cipher++;
3135 	qdf_mem_copy(mccipher_arr, wapi_ie->multicast_cipher_suite,
3136 			CSR_WAPI_OUI_SIZE);
3137 	c_ucast_cipher = (uint8_t) (wapi_ie->unicast_cipher_suite_count);
3138 	c_auth_suites = (uint8_t) (wapi_ie->akm_suite_count);
3139 	for (i = 0; i < c_auth_suites && i < CSR_WAPI_MAX_AUTH_SUITES; i++)
3140 		qdf_mem_copy((void *)&authsuites[i],
3141 			(void *)&wapi_ie->akm_suites[i], CSR_WAPI_OUI_SIZE);
3142 
3143 	wapioui_idx = csr_get_oui_index_from_cipher(encr_type);
3144 	if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) {
3145 		sms_log(mac_ctx, LOGE,
3146 			FL("Wapi OUI index = %d out of limit"),
3147 			wapioui_idx);
3148 		acceptable_cipher = false;
3149 		goto end;
3150 	}
3151 	/* Check - Is requested unicast Cipher supported by the BSS. */
3152 	acceptable_cipher = csr_match_wapi_oui_index(mac_ctx,
3153 				wapi_ie->unicast_cipher_suites,
3154 				c_ucast_cipher, wapioui_idx, unicast);
3155 	if (!acceptable_cipher)
3156 		goto end;
3157 
3158 	/* unicast is supported. Pick the first matching Group cipher, if any */
3159 	for (i = 0; i < mc_encryption->numEntries; i++) {
3160 		wapioui_idx = csr_get_oui_index_from_cipher(
3161 					mc_encryption->encryptionType[i]);
3162 		if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) {
3163 			sms_log(mac_ctx, LOGE,
3164 				FL("Wapi OUI index = %d out of limit"),
3165 				wapioui_idx);
3166 			acceptable_cipher = false;
3167 			break;
3168 		}
3169 		acceptable_cipher = csr_match_wapi_oui_index(mac_ctx,
3170 						mccipher_arr, c_mcast_cipher,
3171 						wapioui_idx, multicast);
3172 		if (acceptable_cipher)
3173 			break;
3174 	}
3175 	if (!acceptable_cipher)
3176 		goto end;
3177 
3178 	if (negotiated_mccipher)
3179 		*negotiated_mccipher =
3180 			mc_encryption->encryptionType[i];
3181 
3182 	/*
3183 	 * Ciphers are supported, Match authentication algorithm and
3184 	 * pick first matching authtype
3185 	 */
3186 	if (csr_is_auth_wapi_cert
3187 			(mac_ctx, authsuites, c_auth_suites, authentication)) {
3188 		neg_authtype =
3189 			eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
3190 	} else if (csr_is_auth_wapi_psk(mac_ctx, authsuites,
3191 				c_auth_suites, authentication)) {
3192 		neg_authtype = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
3193 	} else {
3194 		acceptable_cipher = false;
3195 		neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
3196 	}
3197 
3198 	/* Caller doesn't care about auth type, or BSS doesn't match */
3199 	if ((0 == auth_type->numEntries) || (false == acceptable_cipher))
3200 		goto end;
3201 
3202 	acceptable_cipher = false;
3203 	for (i = 0; i < auth_type->numEntries; i++) {
3204 		if (auth_type->authType[i] == neg_authtype) {
3205 			acceptable_cipher = true;
3206 			break;
3207 		}
3208 	}
3209 
3210 end:
3211 	if (acceptable_cipher) {
3212 		if (mcast_cipher)
3213 			qdf_mem_copy(mcast_cipher, multicast,
3214 					CSR_WAPI_OUI_SIZE);
3215 		if (ucast_cipher)
3216 			qdf_mem_copy(ucast_cipher, unicast, CSR_WAPI_OUI_SIZE);
3217 		if (auth_suite)
3218 			qdf_mem_copy(auth_suite, authentication,
3219 					CSR_WAPI_OUI_SIZE);
3220 		if (negotiated_authtype)
3221 			*negotiated_authtype = neg_authtype;
3222 	}
3223 	return acceptable_cipher;
3224 }
3225 
3226 static bool csr_is_wapi_match(tHalHandle hHal, tCsrAuthList *pAuthType,
3227 			      eCsrEncryptionType enType,
3228 			      tCsrEncryptionList *pEnMcType,
3229 			      tDot11fBeaconIEs *pIes,
3230 			      eCsrAuthType *pNegotiatedAuthType,
3231 			      eCsrEncryptionType *pNegotiatedMCCipher)
3232 {
3233 	bool fWapiMatch = false;
3234 
3235 	/* See if the cyphers in the Bss description match with the settings in the profile. */
3236 	fWapiMatch =
3237 		csr_get_wapi_information(hHal, pAuthType, enType, pEnMcType,
3238 					 &pIes->WAPI, NULL, NULL, NULL,
3239 					 pNegotiatedAuthType,
3240 					 pNegotiatedMCCipher);
3241 
3242 	return fWapiMatch;
3243 }
3244 
3245 static bool csr_lookup_bkid(tpAniSirGlobal pMac, uint32_t sessionId,
3246 			    uint8_t *pBSSId, uint8_t *pBKId)
3247 {
3248 	bool fRC = false, fMatchFound = false;
3249 	uint32_t Index;
3250 	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
3251 
3252 	if (!pSession) {
3253 		sms_log(pMac, LOGE, FL("  session %d not found "), sessionId);
3254 		return false;
3255 	}
3256 
3257 	do {
3258 		for (Index = 0; Index < pSession->NumBkidCache; Index++) {
3259 			sms_log(pMac, LOGW, "match BKID " MAC_ADDRESS_STR " to ",
3260 				MAC_ADDR_ARRAY(pBSSId));
3261 			if (!qdf_mem_cmp
3262 			    (pBSSId, pSession->BkidCacheInfo[Index].BSSID.bytes,
3263 				    sizeof(struct qdf_mac_addr))) {
3264 				/* match found */
3265 				fMatchFound = true;
3266 				break;
3267 			}
3268 		}
3269 
3270 		if (!fMatchFound)
3271 			break;
3272 
3273 		qdf_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID,
3274 			     CSR_WAPI_BKID_SIZE);
3275 
3276 		fRC = true;
3277 	} while (0);
3278 	sms_log(pMac, LOGW,
3279 		"csr_lookup_bkid called return match = %d pMac->roam.NumBkidCache = %d",
3280 		fRC, pSession->NumBkidCache);
3281 
3282 	return fRC;
3283 }
3284 
3285 uint8_t csr_construct_wapi_ie(tpAniSirGlobal pMac, uint32_t sessionId,
3286 			      tCsrRoamProfile *pProfile,
3287 			      tSirBssDescription *pSirBssDesc,
3288 			      tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe)
3289 {
3290 	bool fWapiMatch = false;
3291 	uint8_t cbWapiIe = 0;
3292 	uint8_t UnicastCypher[CSR_WAPI_OUI_SIZE];
3293 	uint8_t MulticastCypher[CSR_WAPI_OUI_SIZE];
3294 	uint8_t AuthSuite[CSR_WAPI_OUI_SIZE];
3295 	uint8_t BKId[CSR_WAPI_BKID_SIZE];
3296 	uint8_t *pWapi = NULL;
3297 	bool fBKIDFound = false;
3298 	tDot11fBeaconIEs *pIesLocal = pIes;
3299 
3300 	do {
3301 		if (!csr_is_profile_wapi(pProfile))
3302 			break;
3303 
3304 		if (!pIesLocal
3305 		    &&
3306 		    (!QDF_IS_STATUS_SUCCESS
3307 			     (csr_get_parsed_bss_description_ies
3308 				     (pMac, pSirBssDesc, &pIesLocal)))) {
3309 			break;
3310 		}
3311 		/* See if the cyphers in the Bss description match with the settings in the profile. */
3312 		fWapiMatch =
3313 			csr_get_wapi_information(pMac, &pProfile->AuthType,
3314 						 pProfile->negotiatedUCEncryptionType,
3315 						 &pProfile->mcEncryptionType,
3316 						 &pIesLocal->WAPI, UnicastCypher,
3317 						 MulticastCypher, AuthSuite, NULL,
3318 						 NULL);
3319 		if (!fWapiMatch)
3320 			break;
3321 
3322 		qdf_mem_set(pWapiIe, sizeof(tCsrWapiIe), 0);
3323 
3324 		pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI;
3325 
3326 		pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED;
3327 
3328 		pWapiIe->cAuthenticationSuites = 1;
3329 		qdf_mem_copy(&pWapiIe->AuthOui[0], AuthSuite,
3330 			     sizeof(AuthSuite));
3331 
3332 		pWapi = (uint8_t *) (&pWapiIe->AuthOui[1]);
3333 
3334 		*pWapi = (uint16_t) 1;  /* cUnicastCyphers */
3335 		pWapi += 2;
3336 		qdf_mem_copy(pWapi, UnicastCypher, sizeof(UnicastCypher));
3337 		pWapi += sizeof(UnicastCypher);
3338 
3339 		qdf_mem_copy(pWapi, MulticastCypher, sizeof(MulticastCypher));
3340 		pWapi += sizeof(MulticastCypher);
3341 
3342 		/* WAPI capabilities follows the Auth Suite (two octects) */
3343 		/* we shouldn't EVER be sending out "pre-auth supported".  It is an AP only capability */
3344 		/* & since we already did a memset pWapiIe to 0, skip these fields */
3345 		pWapi += 2;
3346 
3347 		fBKIDFound =
3348 			csr_lookup_bkid(pMac, sessionId, pSirBssDesc->bssId,
3349 					&(BKId[0]));
3350 
3351 		if (fBKIDFound) {
3352 			/* Do we need to change the endianness here */
3353 			*pWapi = (uint16_t) 1;  /* cBKIDs */
3354 			pWapi += 2;
3355 			qdf_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE);
3356 		} else {
3357 			*pWapi = 0;
3358 			pWapi += 1;
3359 			*pWapi = 0;
3360 			pWapi += 1;
3361 		}
3362 
3363 		/* Add in the IE fields except the IE header */
3364 		/* Add BKID count and BKID (if any) */
3365 		pWapiIe->IeHeader.Length =
3366 			(uint8_t) (sizeof(*pWapiIe) - sizeof(pWapiIe->IeHeader));
3367 
3368 		/*2 bytes for BKID Count field */
3369 		pWapiIe->IeHeader.Length += sizeof(uint16_t);
3370 
3371 		if (fBKIDFound) {
3372 			pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE;
3373 		}
3374 		/* return the size of the IE header (total) constructed... */
3375 		cbWapiIe = pWapiIe->IeHeader.Length + sizeof(pWapiIe->IeHeader);
3376 
3377 	} while (0);
3378 
3379 	if (!pIes && pIesLocal) {
3380 		/* locally allocated */
3381 		qdf_mem_free(pIesLocal);
3382 	}
3383 
3384 	return cbWapiIe;
3385 }
3386 #endif /* FEATURE_WLAN_WAPI */
3387 
3388 /**
3389  * csr_get_wpa_cyphers() - to get WPA cipher info
3390  * @mac_ctx: pointer to mac context
3391  * @auth_type: auth type
3392  * @encr_type: encryption type
3393  * @mc_encryption: multicast encryption type
3394  * @wpa_ie: pointer to WPA IE
3395  * @ucast_cipher: Unicast cipher
3396  * @mcast_cipher: Multicast cipher
3397  * @auth_suite: Authentication suite
3398  * @negotiated_authtype: Negotiated auth type
3399  * @negotiated_mccipher: negotiated multicast cipher
3400  *
3401  * This routine will get all WPA information
3402  *
3403  * Return: bool
3404  */
3405 static bool csr_get_wpa_cyphers(tpAniSirGlobal mac_ctx, tCsrAuthList *auth_type,
3406 				eCsrEncryptionType encr_type,
3407 				tCsrEncryptionList *mc_encryption,
3408 				tDot11fIEWPA *wpa_ie, uint8_t *ucast_cipher,
3409 				uint8_t *mcast_cipher, uint8_t *auth_suite,
3410 				eCsrAuthType *negotiated_authtype,
3411 				eCsrEncryptionType *negotiated_mccipher)
3412 {
3413 	bool acceptable_cipher = false;
3414 	uint8_t c_ucast_cipher = 0;
3415 	uint8_t c_mcast_cipher = 0;
3416 	uint8_t c_auth_suites = 0;
3417 	uint8_t unicast[CSR_WPA_OUI_SIZE];
3418 	uint8_t multicast[CSR_WPA_OUI_SIZE];
3419 	uint8_t authentication[CSR_WPA_OUI_SIZE];
3420 	uint8_t mccipher_arr[1][CSR_WPA_OUI_SIZE];
3421 	uint8_t i;
3422 	eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
3423 
3424 	if (!wpa_ie->present)
3425 		goto end;
3426 	c_mcast_cipher = 1;
3427 	qdf_mem_copy(mccipher_arr, wpa_ie->multicast_cipher, CSR_WPA_OUI_SIZE);
3428 	c_ucast_cipher = (uint8_t) (wpa_ie->unicast_cipher_count);
3429 	c_auth_suites = (uint8_t) (wpa_ie->auth_suite_count);
3430 
3431 	/* Check - Is requested unicast Cipher supported by the BSS. */
3432 	acceptable_cipher = csr_match_wpaoui_index(mac_ctx,
3433 				wpa_ie->unicast_ciphers, c_ucast_cipher,
3434 				csr_get_oui_index_from_cipher(encr_type),
3435 				unicast);
3436 	if (!acceptable_cipher)
3437 		goto end;
3438 	/* unicast is supported. Pick the first matching Group cipher, if any */
3439 	for (i = 0; i < mc_encryption->numEntries; i++) {
3440 		acceptable_cipher = csr_match_wpaoui_index(mac_ctx,
3441 					mccipher_arr, c_mcast_cipher,
3442 					csr_get_oui_index_from_cipher(
3443 					    mc_encryption->encryptionType[i]),
3444 					multicast);
3445 		if (acceptable_cipher)
3446 			break;
3447 	}
3448 	if (!acceptable_cipher)
3449 		goto end;
3450 
3451 	if (negotiated_mccipher)
3452 		*negotiated_mccipher = mc_encryption->encryptionType[i];
3453 
3454 	/* Initializing with false as it has true value already */
3455 	acceptable_cipher = false;
3456 	for (i = 0; i < auth_type->numEntries; i++) {
3457 		/*
3458 		 * Ciphers are supported, Match authentication algorithm and
3459 		 * pick first matching authtype
3460 		 */
3461 		if (csr_is_auth_wpa(mac_ctx, wpa_ie->auth_suites, c_auth_suites,
3462 			authentication)) {
3463 			if (eCSR_AUTH_TYPE_WPA == auth_type->authType[i])
3464 				neg_authtype = eCSR_AUTH_TYPE_WPA;
3465 		}
3466 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
3467 			csr_is_auth_wpa_psk(mac_ctx,
3468 				wpa_ie->auth_suites, c_auth_suites,
3469 				authentication)) {
3470 			if (eCSR_AUTH_TYPE_WPA_PSK == auth_type->authType[i])
3471 				neg_authtype = eCSR_AUTH_TYPE_WPA_PSK;
3472 		}
3473 #ifdef FEATURE_WLAN_ESE
3474 		if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
3475 			&& csr_is_ese_cckm_auth_wpa(mac_ctx,
3476 				wpa_ie->auth_suites, c_auth_suites,
3477 				authentication)) {
3478 			if (eCSR_AUTH_TYPE_CCKM_WPA == auth_type->authType[i])
3479 				neg_authtype = eCSR_AUTH_TYPE_CCKM_WPA;
3480 		}
3481 #endif /* FEATURE_WLAN_ESE */
3482 
3483 		/*
3484 		 * The 1st auth type in the APs WPA IE, to match stations
3485 		 * connecting profiles auth type will cause us to exit this
3486 		 * loop. This is added as some APs advertise multiple akms in
3487 		 * the WPA IE
3488 		 */
3489 		if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) {
3490 			acceptable_cipher = true;
3491 			break;
3492 		}
3493 	}
3494 
3495 end:
3496 	if (acceptable_cipher) {
3497 		if (mcast_cipher)
3498 			qdf_mem_copy((uint8_t **) mcast_cipher, multicast,
3499 					CSR_WPA_OUI_SIZE);
3500 
3501 		if (ucast_cipher)
3502 			qdf_mem_copy((uint8_t **) ucast_cipher, unicast,
3503 					CSR_WPA_OUI_SIZE);
3504 
3505 		if (auth_suite)
3506 			qdf_mem_copy((uint8_t **) auth_suite, authentication,
3507 					CSR_WPA_OUI_SIZE);
3508 
3509 		if (negotiated_authtype)
3510 			*negotiated_authtype = neg_authtype;
3511 	}
3512 
3513 	return acceptable_cipher;
3514 }
3515 
3516 static bool csr_is_wpa_encryption_match(tpAniSirGlobal pMac,
3517 					tCsrAuthList *pAuthType,
3518 					eCsrEncryptionType enType,
3519 					tCsrEncryptionList *pEnMcType,
3520 					tDot11fBeaconIEs *pIes,
3521 					eCsrAuthType *pNegotiatedAuthtype,
3522 					eCsrEncryptionType *pNegotiatedMCCipher)
3523 {
3524 	bool fWpaMatch = false;
3525 
3526 	/* See if the cyphers in the Bss description match with the settings in the profile. */
3527 	fWpaMatch =
3528 		csr_get_wpa_cyphers(pMac, pAuthType, enType, pEnMcType, &pIes->WPA,
3529 				    NULL, NULL, NULL, pNegotiatedAuthtype,
3530 				    pNegotiatedMCCipher);
3531 
3532 	return fWpaMatch;
3533 }
3534 
3535 uint8_t csr_construct_wpa_ie(tHalHandle hHal, tCsrRoamProfile *pProfile,
3536 			     tSirBssDescription *pSirBssDesc,
3537 			     tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe)
3538 {
3539 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3540 	bool fWpaMatch;
3541 	uint8_t cbWpaIe = 0;
3542 	uint8_t UnicastCypher[CSR_WPA_OUI_SIZE];
3543 	uint8_t MulticastCypher[CSR_WPA_OUI_SIZE];
3544 	uint8_t AuthSuite[CSR_WPA_OUI_SIZE];
3545 	tCsrWpaAuthIe *pAuthSuite;
3546 	tDot11fBeaconIEs *pIesLocal = pIes;
3547 
3548 	do {
3549 		if (!csr_is_profile_wpa(pProfile))
3550 			break;
3551 
3552 		if (!pIesLocal
3553 		    &&
3554 		    (!QDF_IS_STATUS_SUCCESS
3555 			     (csr_get_parsed_bss_description_ies
3556 				     (pMac, pSirBssDesc, &pIesLocal)))) {
3557 			break;
3558 		}
3559 		/* See if the cyphers in the Bss description match with the settings in the profile. */
3560 		fWpaMatch =
3561 			csr_get_wpa_cyphers(hHal, &pProfile->AuthType,
3562 					    pProfile->negotiatedUCEncryptionType,
3563 					    &pProfile->mcEncryptionType,
3564 					    &pIesLocal->WPA, UnicastCypher,
3565 					    MulticastCypher, AuthSuite, NULL, NULL);
3566 		if (!fWpaMatch)
3567 			break;
3568 
3569 		pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID;
3570 
3571 		qdf_mem_copy(pWpaIe->Oui, csr_wpa_oui[01], sizeof(pWpaIe->Oui));
3572 
3573 		pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED;
3574 
3575 		qdf_mem_copy(pWpaIe->MulticastOui, MulticastCypher,
3576 			     sizeof(MulticastCypher));
3577 
3578 		pWpaIe->cUnicastCyphers = 1;
3579 
3580 		qdf_mem_copy(&pWpaIe->UnicastOui[0], UnicastCypher,
3581 			     sizeof(UnicastCypher));
3582 
3583 		pAuthSuite =
3584 			(tCsrWpaAuthIe *) (&pWpaIe->
3585 					   UnicastOui[pWpaIe->cUnicastCyphers]);
3586 
3587 		pAuthSuite->cAuthenticationSuites = 1;
3588 		qdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite,
3589 			     sizeof(AuthSuite));
3590 
3591 		/* The WPA capabilities follows the Auth Suite (two octects)-- */
3592 		/* this field is optional, and we always "send" zero, so just */
3593 		/* remove it.  This is consistent with our assumptions in the */
3594 		/* frames compiler; c.f. bug 15234: */
3595 		/* http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234 */
3596 
3597 		/* Add in the fixed fields plus 1 Unicast cypher, less the IE Header length */
3598 		/* Add in the size of the Auth suite (count plus a single OUI) */
3599 		pWpaIe->IeHeader.Length =
3600 			sizeof(*pWpaIe) - sizeof(pWpaIe->IeHeader) +
3601 			sizeof(*pAuthSuite);
3602 
3603 		/* return the size of the IE header (total) constructed... */
3604 		cbWpaIe = pWpaIe->IeHeader.Length + sizeof(pWpaIe->IeHeader);
3605 
3606 	} while (0);
3607 
3608 	if (!pIes && pIesLocal) {
3609 		/* locally allocated */
3610 		qdf_mem_free(pIesLocal);
3611 	}
3612 
3613 	return cbWpaIe;
3614 }
3615 
3616 /* If a WPAIE exists in the profile, just use it. Or else construct one from the BSS */
3617 /* Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE */
3618 uint8_t csr_retrieve_wpa_ie(tHalHandle hHal, tCsrRoamProfile *pProfile,
3619 			    tSirBssDescription *pSirBssDesc,
3620 			    tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe)
3621 {
3622 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3623 	uint8_t cbWpaIe = 0;
3624 
3625 	do {
3626 		if (!csr_is_profile_wpa(pProfile))
3627 			break;
3628 		if (pProfile->nWPAReqIELength && pProfile->pWPAReqIE) {
3629 			if (SIR_MAC_WPA_IE_MAX_LENGTH >=
3630 			    pProfile->nWPAReqIELength) {
3631 				cbWpaIe = (uint8_t) pProfile->nWPAReqIELength;
3632 				qdf_mem_copy(pWpaIe, pProfile->pWPAReqIE,
3633 					     cbWpaIe);
3634 			} else {
3635 				sms_log(pMac, LOGW,
3636 					"  csr_retrieve_wpa_ie detect invalid WPA IE length (%d) ",
3637 					pProfile->nWPAReqIELength);
3638 			}
3639 		} else {
3640 			cbWpaIe =
3641 				csr_construct_wpa_ie(pMac, pProfile, pSirBssDesc, pIes,
3642 						     pWpaIe);
3643 		}
3644 	} while (0);
3645 
3646 	return cbWpaIe;
3647 }
3648 
3649 /* If a RSNIE exists in the profile, just use it. Or else construct one from the BSS */
3650 /* Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE */
3651 uint8_t csr_retrieve_rsn_ie(tHalHandle hHal, uint32_t sessionId,
3652 			    tCsrRoamProfile *pProfile,
3653 			    tSirBssDescription *pSirBssDesc,
3654 			    tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe)
3655 {
3656 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3657 	uint8_t cbRsnIe = 0;
3658 
3659 	do {
3660 		if (!csr_is_profile_rsn(pProfile))
3661 			break;
3662 		if (csr_roam_is_fast_roam_enabled(pMac, sessionId)) {
3663 			/* If "Legacy Fast Roaming" is enabled ALWAYS rebuild the RSN IE from */
3664 			/* scratch. So it contains the current PMK-IDs */
3665 			cbRsnIe =
3666 				csr_construct_rsn_ie(pMac, sessionId, pProfile,
3667 						     pSirBssDesc, pIes, pRsnIe);
3668 		} else if (pProfile->nRSNReqIELength && pProfile->pRSNReqIE) {
3669 			/* If you have one started away, re-use it. */
3670 			if (SIR_MAC_WPA_IE_MAX_LENGTH >=
3671 			    pProfile->nRSNReqIELength) {
3672 				cbRsnIe = (uint8_t) pProfile->nRSNReqIELength;
3673 				qdf_mem_copy(pRsnIe, pProfile->pRSNReqIE,
3674 					     cbRsnIe);
3675 			} else {
3676 				sms_log(pMac, LOGW,
3677 					"  csr_retrieve_rsn_ie detect invalid RSN IE length (%d) ",
3678 					pProfile->nRSNReqIELength);
3679 			}
3680 		} else {
3681 			cbRsnIe =
3682 				csr_construct_rsn_ie(pMac, sessionId, pProfile,
3683 						     pSirBssDesc, pIes, pRsnIe);
3684 		}
3685 	} while (0);
3686 
3687 	return cbRsnIe;
3688 }
3689 
3690 #ifdef FEATURE_WLAN_WAPI
3691 /* If a WAPI IE exists in the profile, just use it. Or else construct one from the BSS */
3692 /* Caller allocated memory for pWapiIe and guarrantee it can contain a max length WAPI IE */
3693 uint8_t csr_retrieve_wapi_ie(tHalHandle hHal, uint32_t sessionId,
3694 			     tCsrRoamProfile *pProfile,
3695 			     tSirBssDescription *pSirBssDesc,
3696 			     tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe)
3697 {
3698 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3699 	uint8_t cbWapiIe = 0;
3700 
3701 	do {
3702 		if (!csr_is_profile_wapi(pProfile))
3703 			break;
3704 		if (pProfile->nWAPIReqIELength && pProfile->pWAPIReqIE) {
3705 			if (DOT11F_IE_WAPI_MAX_LEN >=
3706 			    pProfile->nWAPIReqIELength) {
3707 				cbWapiIe = (uint8_t) pProfile->nWAPIReqIELength;
3708 				qdf_mem_copy(pWapiIe, pProfile->pWAPIReqIE,
3709 					     cbWapiIe);
3710 			} else {
3711 				sms_log(pMac, LOGW,
3712 					"  csr_retrieve_wapi_ie detect invalid WAPI IE length (%d) ",
3713 					pProfile->nWAPIReqIELength);
3714 			}
3715 		} else {
3716 			cbWapiIe =
3717 				csr_construct_wapi_ie(pMac, sessionId, pProfile,
3718 						      pSirBssDesc, pIes, pWapiIe);
3719 		}
3720 	} while (0);
3721 
3722 	return cbWapiIe;
3723 }
3724 #endif /* FEATURE_WLAN_WAPI */
3725 
3726 bool csr_rates_is_dot11_rate11b_supported_rate(uint8_t dot11Rate)
3727 {
3728 	bool fSupported = false;
3729 	uint16_t nonBasicRate =
3730 		(uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK));
3731 
3732 	switch (nonBasicRate) {
3733 	case eCsrSuppRate_1Mbps:
3734 	case eCsrSuppRate_2Mbps:
3735 	case eCsrSuppRate_5_5Mbps:
3736 	case eCsrSuppRate_11Mbps:
3737 		fSupported = true;
3738 		break;
3739 
3740 	default:
3741 		break;
3742 	}
3743 
3744 	return fSupported;
3745 }
3746 
3747 bool csr_rates_is_dot11_rate11a_supported_rate(uint8_t dot11Rate)
3748 {
3749 	bool fSupported = false;
3750 	uint16_t nonBasicRate =
3751 		(uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK));
3752 
3753 	switch (nonBasicRate) {
3754 	case eCsrSuppRate_6Mbps:
3755 	case eCsrSuppRate_9Mbps:
3756 	case eCsrSuppRate_12Mbps:
3757 	case eCsrSuppRate_18Mbps:
3758 	case eCsrSuppRate_24Mbps:
3759 	case eCsrSuppRate_36Mbps:
3760 	case eCsrSuppRate_48Mbps:
3761 	case eCsrSuppRate_54Mbps:
3762 		fSupported = true;
3763 		break;
3764 
3765 	default:
3766 		break;
3767 	}
3768 
3769 	return fSupported;
3770 }
3771 
3772 tAniEdType csr_translate_encrypt_type_to_ed_type(eCsrEncryptionType EncryptType)
3773 {
3774 	tAniEdType edType;
3775 
3776 	switch (EncryptType) {
3777 	default:
3778 	case eCSR_ENCRYPT_TYPE_NONE:
3779 		edType = eSIR_ED_NONE;
3780 		break;
3781 
3782 	case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3783 	case eCSR_ENCRYPT_TYPE_WEP40:
3784 		edType = eSIR_ED_WEP40;
3785 		break;
3786 
3787 	case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3788 	case eCSR_ENCRYPT_TYPE_WEP104:
3789 		edType = eSIR_ED_WEP104;
3790 		break;
3791 
3792 	case eCSR_ENCRYPT_TYPE_TKIP:
3793 		edType = eSIR_ED_TKIP;
3794 		break;
3795 
3796 	case eCSR_ENCRYPT_TYPE_AES:
3797 		edType = eSIR_ED_CCMP;
3798 		break;
3799 #ifdef FEATURE_WLAN_WAPI
3800 	case eCSR_ENCRYPT_TYPE_WPI:
3801 		edType = eSIR_ED_WPI;
3802 		break;
3803 #endif
3804 #ifdef WLAN_FEATURE_11W
3805 	/* 11w BIP */
3806 	case eCSR_ENCRYPT_TYPE_AES_CMAC:
3807 		edType = eSIR_ED_AES_128_CMAC;
3808 		break;
3809 #endif
3810 	}
3811 
3812 	return edType;
3813 }
3814 
3815 /**
3816  * csr_validate_wep() - to validate wep
3817  * @uc_encry_type: unicast encryption type
3818  * @auth_list: Auth list
3819  * @mc_encryption_list: multicast encryption type
3820  * @negotiated_authtype: negotiated auth type
3821  * @negotiated_mc_encry: negotiated mc encry type
3822  * @bss_descr: BSS description
3823  * @ie_ptr: IE pointer
3824  *
3825  * This function just checks whether HDD is giving correct values for
3826  * Multicast cipher and Auth
3827  *
3828  * Return: bool
3829  */
3830 static bool csr_validate_wep(tpAniSirGlobal mac_ctx,
3831 			     eCsrEncryptionType uc_encry_type,
3832 			     tCsrAuthList *auth_list,
3833 			     tCsrEncryptionList *mc_encryption_list,
3834 			     eCsrAuthType *negotiated_authtype,
3835 			     eCsrEncryptionType *negotiated_mc_encry,
3836 			     tSirBssDescription *bss_descr,
3837 			     tDot11fBeaconIEs *ie_ptr)
3838 {
3839 	uint32_t idx;
3840 	bool match = false;
3841 	eCsrAuthType negotiated_auth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
3842 	eCsrEncryptionType negotiated_mccipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
3843 
3844 	/* If privacy bit is not set, consider no match */
3845 	if (!csr_is_privacy(bss_descr))
3846 		goto end;
3847 
3848 	for (idx = 0; idx < mc_encryption_list->numEntries; idx++) {
3849 		switch (mc_encryption_list->encryptionType[idx]) {
3850 		case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3851 		case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3852 		case eCSR_ENCRYPT_TYPE_WEP40:
3853 		case eCSR_ENCRYPT_TYPE_WEP104:
3854 			/*
3855 			 * Multicast list may contain WEP40/WEP104.
3856 			 * Check whether it matches UC.
3857 			 */
3858 			if (uc_encry_type ==
3859 				mc_encryption_list->encryptionType[idx]) {
3860 				match = true;
3861 				negotiated_mccipher =
3862 					mc_encryption_list->encryptionType[idx];
3863 			}
3864 			break;
3865 		default:
3866 			match = false;
3867 			break;
3868 		}
3869 		if (match)
3870 			break;
3871 	}
3872 
3873 	if (!match)
3874 		goto end;
3875 
3876 	for (idx = 0; idx < auth_list->numEntries; idx++) {
3877 		switch (auth_list->authType[idx]) {
3878 		case eCSR_AUTH_TYPE_OPEN_SYSTEM:
3879 		case eCSR_AUTH_TYPE_SHARED_KEY:
3880 		case eCSR_AUTH_TYPE_AUTOSWITCH:
3881 			match = true;
3882 			negotiated_auth = auth_list->authType[idx];
3883 			break;
3884 		default:
3885 			match = false;
3886 		}
3887 		if (match)
3888 			break;
3889 	}
3890 
3891 	if (!match)
3892 		goto end;
3893 
3894 	if (!ie_ptr)
3895 		goto end;
3896 
3897 	/*
3898 	 * In case of WPA / WPA2, check whether it supports WEP as well.
3899 	 * Prepare the encryption type for WPA/WPA2 functions
3900 	 */
3901 	if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == uc_encry_type)
3902 		uc_encry_type = eCSR_ENCRYPT_TYPE_WEP40;
3903 	else if (eCSR_ENCRYPT_TYPE_WEP104 == uc_encry_type)
3904 		uc_encry_type = eCSR_ENCRYPT_TYPE_WEP104;
3905 
3906 	/* else we can use the encryption type directly */
3907 	if (ie_ptr->WPA.present) {
3908 		match = (!qdf_mem_cmp(ie_ptr->WPA.multicast_cipher,
3909 				csr_wpa_oui[csr_get_oui_index_from_cipher(
3910 					uc_encry_type)],
3911 				CSR_WPA_OUI_SIZE));
3912 		if (match)
3913 			goto end;
3914 	}
3915 	if (ie_ptr->RSN.present) {
3916 		match = (!qdf_mem_cmp(ie_ptr->RSN.gp_cipher_suite,
3917 				csr_rsn_oui[csr_get_oui_index_from_cipher(
3918 					uc_encry_type)],
3919 				CSR_RSN_OUI_SIZE));
3920 	}
3921 
3922 
3923 end:
3924 	if (match) {
3925 		if (negotiated_authtype)
3926 			*negotiated_authtype = negotiated_auth;
3927 		if (negotiated_mc_encry)
3928 			*negotiated_mc_encry = negotiated_mccipher;
3929 	}
3930 	return match;
3931 }
3932 
3933 /**
3934  * csr_validate_open_none() - Check if the security is matching
3935  * @bss_desc:          BSS Descriptor on which the check is done
3936  * @mc_enc_type:       Multicast encryption type
3937  * @mc_cipher:         Multicast Cipher
3938  * @auth_type:         Authentication type
3939  * @neg_auth_type:     Negotiated Auth type with the AP
3940  *
3941  * Return: Boolean value to tell if matched or not.
3942  */
3943 static bool csr_validate_open_none(tSirBssDescription *bss_desc,
3944 	tCsrEncryptionList *mc_enc_type, eCsrEncryptionType *mc_cipher,
3945 	tCsrAuthList *auth_type, eCsrAuthType *neg_auth_type)
3946 {
3947 	bool match;
3948 	uint8_t idx;
3949 
3950 	/*
3951 	 * for NO encryption, if the Bss description has the
3952 	 * Privacy bit turned on, then encryption is required
3953 	 * so we have to reject this Bss.
3954 	 */
3955 	if (csr_is_privacy(bss_desc))
3956 		match = false;
3957 	else
3958 		match = true;
3959 	if (match) {
3960 		match = false;
3961 		/* Check MC cipher and Auth type requested. */
3962 		for (idx = 0; idx < mc_enc_type->numEntries; idx++) {
3963 			if (eCSR_ENCRYPT_TYPE_NONE ==
3964 				mc_enc_type->encryptionType[idx]) {
3965 				match = true;
3966 				*mc_cipher = mc_enc_type->encryptionType[idx];
3967 				break;
3968 			}
3969 		}
3970 		if (!match)
3971 			return match;
3972 
3973 		match = false;
3974 		/* Check Auth list. It should contain AuthOpen. */
3975 		for (idx = 0; idx < auth_type->numEntries; idx++) {
3976 			if ((eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3977 				auth_type->authType[idx]) ||
3978 				(eCSR_AUTH_TYPE_AUTOSWITCH ==
3979 				auth_type->authType[idx])) {
3980 				match = true;
3981 				*neg_auth_type =
3982 					eCSR_AUTH_TYPE_OPEN_SYSTEM;
3983 				break;
3984 			}
3985 		}
3986 		if (!match)
3987 			return match;
3988 
3989 	}
3990 	return match;
3991 }
3992 
3993 /**
3994  * csr_validate_any_default() - Check if the security is matching
3995  * @hal:               Global HAL handle
3996  * @auth_type:         Authentication type
3997  * @mc_enc_type:       Multicast encryption type
3998  * @mfp_enabled:       Management frame protection feature
3999  * @mfp_required:      Mangement frame protection mandatory
4000  * @mfp_capable:       Device capable of MFP
4001  * @ies_ptr:           Pointer to the IE fields
4002  * @neg_auth_type:     Negotiated Auth type with the AP
4003  * @bss_desc:          BSS Descriptor
4004  * @neg_uc_cipher:     Negotiated unicast cipher suite
4005  * @neg_mc_cipher:     Negotiated multicast cipher
4006  *
4007  * Return: Boolean value to tell if matched or not.
4008  */
4009 static bool csr_validate_any_default(tHalHandle hal, tCsrAuthList *auth_type,
4010 	tCsrEncryptionList *mc_enc_type, bool *mfp_enabled,
4011 	uint8_t *mfp_required, uint8_t *mfp_capable,
4012 	tDot11fBeaconIEs *ies_ptr, eCsrAuthType *neg_auth_type,
4013 	tSirBssDescription *bss_desc, eCsrEncryptionType *uc_cipher,
4014 	eCsrEncryptionType *mc_cipher)
4015 {
4016 	bool match_any = false;
4017 	bool match = true;
4018 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4019 	/* It is allowed to match anything. Try the more secured ones first. */
4020 	if (ies_ptr) {
4021 		/* Check AES first */
4022 		*uc_cipher = eCSR_ENCRYPT_TYPE_AES;
4023 		match_any = csr_is_rsn_match(hal, auth_type,
4024 				*uc_cipher, mc_enc_type, mfp_enabled,
4025 				mfp_required, mfp_capable, ies_ptr,
4026 				neg_auth_type, mc_cipher);
4027 		if (!match_any) {
4028 			/* Check TKIP */
4029 			*uc_cipher = eCSR_ENCRYPT_TYPE_TKIP;
4030 			match_any = csr_is_rsn_match(hal, auth_type, *uc_cipher,
4031 					mc_enc_type, mfp_enabled, mfp_required,
4032 					mfp_capable, ies_ptr, neg_auth_type,
4033 					mc_cipher);
4034 		}
4035 #ifdef FEATURE_WLAN_WAPI
4036 		if (!match_any) {
4037 			/* Check WAPI */
4038 			*uc_cipher = eCSR_ENCRYPT_TYPE_WPI;
4039 			match_any = csr_is_wapi_match(hal, auth_type,
4040 					*uc_cipher, mc_enc_type, ies_ptr,
4041 					neg_auth_type, mc_cipher);
4042 		}
4043 #endif
4044 	}
4045 	if (match_any)
4046 		return match;
4047 	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP104;
4048 	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
4049 			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
4050 		return match;
4051 	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP40;
4052 	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
4053 			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
4054 		return match;
4055 	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4056 	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
4057 			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
4058 		return match;
4059 	*uc_cipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4060 	if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
4061 			neg_auth_type, mc_cipher, bss_desc, ies_ptr))
4062 		return match;
4063 	/* It must be open and no enc */
4064 	if (csr_is_privacy(bss_desc)) {
4065 		match = false;
4066 		return match;
4067 	}
4068 
4069 	*neg_auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4070 	*mc_cipher = eCSR_ENCRYPT_TYPE_NONE;
4071 	*uc_cipher = eCSR_ENCRYPT_TYPE_NONE;
4072 	return match;
4073 
4074 }
4075 
4076 /**
4077  * csr_is_security_match() - Check if the security is matching
4078  * @hal:               Global HAL handle
4079  * @auth_type:         Authentication type
4080  * @uc_enc_type:       Unicast Encryption type
4081  * @mc_enc_type:       Multicast encryption type
4082  * @mfp_enabled:       Management frame protection feature
4083  * @mfp_required:      Mangement frame protection mandatory
4084  * @mfp_capable:       Device capable of MFP
4085  * @bss_desc:          BSS Descriptor
4086  * @ies_ptr:           Pointer to the IE fields
4087  * @neg_auth_type:     Negotiated Auth type with the AP
4088  * @neg_uc_cipher:     Negotiated unicast cipher suite
4089  * @neg_mc_cipher:     Negotiated multicast cipher
4090  *
4091  * Return: Boolean value to tell if matched or not.
4092  */
4093 bool csr_is_security_match(tHalHandle hal, tCsrAuthList *auth_type,
4094 	tCsrEncryptionList *uc_enc_type,
4095 	tCsrEncryptionList *mc_enc_type, bool *mfp_enabled,
4096 	uint8_t *mfp_required, uint8_t *mfp_capable,
4097 	tSirBssDescription *bss_desc, tDot11fBeaconIEs *ies_ptr,
4098 	eCsrAuthType *neg_auth_type,
4099 	eCsrEncryptionType *neg_uc_cipher,
4100 	eCsrEncryptionType *neg_mc_cipher)
4101 {
4102 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4103 	bool match = false;
4104 	uint8_t i;
4105 	eCsrEncryptionType mc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
4106 	eCsrEncryptionType uc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
4107 	eCsrAuthType local_neg_auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4108 
4109 	for (i = 0; ((i < uc_enc_type->numEntries) && (!match)); i++) {
4110 		uc_cipher = uc_enc_type->encryptionType[i];
4111 		/*
4112 		 * If the Bss description shows the Privacy bit is on, then we
4113 		 * must have some sort of encryption configured for the profile
4114 		 * to work.  Don't attempt to join networks with Privacy bit
4115 		 * set when profiles say NONE for encryption type.
4116 		 */
4117 		switch (uc_cipher) {
4118 		case eCSR_ENCRYPT_TYPE_NONE:
4119 			match = csr_validate_open_none(bss_desc, mc_enc_type,
4120 					&mc_cipher, auth_type,
4121 					&local_neg_auth_type);
4122 			break;
4123 
4124 		case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4125 		case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4126 			/*
4127 			 * !! might want to check for WEP keys set in the
4128 			 * Profile.... ? !! don't need to have the privacy bit
4129 			 * in the Bss description.  Many AP policies make
4130 			 * legacy encryption 'optional' so we don't know if we
4131 			 * can associate or not.  The AP will reject if
4132 			 * encryption is not allowed without the Privacy bit
4133 			 * turned on.
4134 			 */
4135 			match = csr_validate_wep(mac_ctx, uc_cipher, auth_type,
4136 					mc_enc_type, &local_neg_auth_type,
4137 					&mc_cipher, bss_desc, ies_ptr);
4138 
4139 			break;
4140 		/* these are all of the WPA encryption types... */
4141 		case eCSR_ENCRYPT_TYPE_WEP40:
4142 		case eCSR_ENCRYPT_TYPE_WEP104:
4143 			match = csr_validate_wep(mac_ctx, uc_cipher, auth_type,
4144 					mc_enc_type, &local_neg_auth_type,
4145 					&mc_cipher, bss_desc, ies_ptr);
4146 			break;
4147 
4148 		case eCSR_ENCRYPT_TYPE_TKIP:
4149 		case eCSR_ENCRYPT_TYPE_AES:
4150 			if (!ies_ptr) {
4151 				match = false;
4152 				break;
4153 			}
4154 			/* First check if there is a RSN match */
4155 			match = csr_is_rsn_match(mac_ctx, auth_type,
4156 					uc_cipher, mc_enc_type,
4157 					mfp_enabled, mfp_required,
4158 					mfp_capable, ies_ptr,
4159 					&local_neg_auth_type,
4160 					&mc_cipher);
4161 			/* If not RSN, then check WPA match */
4162 			if (!match)
4163 				match = csr_is_wpa_encryption_match(
4164 						mac_ctx, auth_type,
4165 						uc_cipher, mc_enc_type,
4166 						ies_ptr,
4167 						&local_neg_auth_type,
4168 						&mc_cipher);
4169 			break;
4170 #ifdef FEATURE_WLAN_WAPI
4171 		case eCSR_ENCRYPT_TYPE_WPI:     /* WAPI */
4172 			if (ies_ptr)
4173 				match = csr_is_wapi_match(hal, auth_type,
4174 						uc_cipher, mc_enc_type, ies_ptr,
4175 						&local_neg_auth_type,
4176 						&mc_cipher);
4177 			else
4178 				match = false;
4179 			break;
4180 #endif /* FEATURE_WLAN_WAPI */
4181 		case eCSR_ENCRYPT_TYPE_ANY:
4182 		default:
4183 			match  = csr_validate_any_default(hal, auth_type,
4184 					mc_enc_type, mfp_enabled, mfp_required,
4185 					mfp_capable, ies_ptr,
4186 					&local_neg_auth_type, bss_desc,
4187 					&uc_cipher, &mc_cipher);
4188 			break;
4189 		}
4190 
4191 	}
4192 
4193 	if (match) {
4194 		if (neg_uc_cipher)
4195 			*neg_uc_cipher = uc_cipher;
4196 		if (neg_mc_cipher)
4197 			*neg_mc_cipher = mc_cipher;
4198 		if (neg_auth_type)
4199 			*neg_auth_type = local_neg_auth_type;
4200 	}
4201 	return match;
4202 }
4203 
4204 bool csr_is_ssid_match(tpAniSirGlobal pMac, uint8_t *ssid1, uint8_t ssid1Len,
4205 		       uint8_t *bssSsid, uint8_t bssSsidLen, bool fSsidRequired)
4206 {
4207 	bool fMatch = false;
4208 
4209 	do {
4210 		/*
4211 		 * Check for the specification of the Broadcast SSID at the
4212 		 * beginning of the list. If specified, then all SSIDs are
4213 		 * matches (broadcast SSID means accept all SSIDs).
4214 		 */
4215 		if (ssid1Len == 0) {
4216 			fMatch = true;
4217 			break;
4218 		}
4219 
4220 		/* There are a few special cases.  If the Bss description has a Broadcast SSID, */
4221 		/* then our Profile must have a single SSID without Wildcards so we can program */
4222 		/* the SSID. */
4223 		/* SSID could be suppressed in beacons. In that case SSID IE has valid length */
4224 		/* but the SSID value is all NULL characters. That condition is trated same */
4225 		/* as NULL SSID */
4226 		if (csr_is_nullssid(bssSsid, bssSsidLen)) {
4227 			if (false == fSsidRequired) {
4228 				fMatch = true;
4229 				break;
4230 			}
4231 		}
4232 
4233 		if (ssid1Len != bssSsidLen)
4234 			break;
4235 		if (!qdf_mem_cmp(bssSsid, ssid1, bssSsidLen)) {
4236 			fMatch = true;
4237 			break;
4238 		}
4239 
4240 	} while (0);
4241 
4242 	return fMatch;
4243 }
4244 
4245 /* Null ssid means match */
4246 bool csr_is_ssid_in_list(tHalHandle hHal, tSirMacSSid *pSsid,
4247 			 tCsrSSIDs *pSsidList)
4248 {
4249 	bool fMatch = false;
4250 	uint32_t i;
4251 
4252 	if (pSsidList && pSsid) {
4253 		for (i = 0; i < pSsidList->numOfSSIDs; i++) {
4254 			if (csr_is_nullssid
4255 				    (pSsidList->SSIDList[i].SSID.ssId,
4256 				    pSsidList->SSIDList[i].SSID.length)
4257 			    ||
4258 			    ((pSsidList->SSIDList[i].SSID.length ==
4259 			      pSsid->length)
4260 			     && (!qdf_mem_cmp(pSsid->ssId,
4261 						pSsidList->SSIDList[i].SSID.
4262 						ssId, pSsid->length)))) {
4263 				fMatch = true;
4264 				break;
4265 			}
4266 		}
4267 	}
4268 
4269 	return fMatch;
4270 }
4271 
4272 bool csr_is_bssid_match(tHalHandle hHal, struct qdf_mac_addr *pProfBssid,
4273 			struct qdf_mac_addr *BssBssid)
4274 {
4275 	bool fMatch = false;
4276 	struct qdf_mac_addr ProfileBssid;
4277 
4278 	/* for efficiency of the MAC_ADDRESS functions, move the */
4279 	/* Bssid's into MAC_ADDRESS structs. */
4280 	qdf_mem_copy(&ProfileBssid, pProfBssid, sizeof(struct qdf_mac_addr));
4281 
4282 	do {
4283 
4284 		/* Give the profile the benefit of the doubt... accept either all 0 or */
4285 		/* the real broadcast Bssid (all 0xff) as broadcast Bssids (meaning to */
4286 		/* match any Bssids). */
4287 		if (qdf_is_macaddr_zero(&ProfileBssid) ||
4288 		    qdf_is_macaddr_broadcast(&ProfileBssid)) {
4289 			fMatch = true;
4290 			break;
4291 		}
4292 
4293 		if (qdf_is_macaddr_equal(BssBssid, &ProfileBssid)) {
4294 			fMatch = true;
4295 			break;
4296 		}
4297 
4298 	} while (0);
4299 
4300 	return fMatch;
4301 }
4302 
4303 bool csr_is_bss_type_match(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2)
4304 {
4305 	if ((eCSR_BSS_TYPE_ANY != bssType1 && eCSR_BSS_TYPE_ANY != bssType2)
4306 	    && (bssType1 != bssType2))
4307 		return false;
4308 	else
4309 		return true;
4310 }
4311 
4312 bool csr_is_bss_type_ibss(eCsrRoamBssType bssType)
4313 {
4314 	return (bool)
4315 		(eCSR_BSS_TYPE_START_IBSS == bssType
4316 		 || eCSR_BSS_TYPE_IBSS == bssType);
4317 }
4318 
4319 
4320 static bool csr_is_bss_type_caps_match(eCsrRoamBssType bssType,
4321 				       tSirBssDescription *pSirBssDesc)
4322 {
4323 	bool fMatch = true;
4324 
4325 	do {
4326 		switch (bssType) {
4327 		case eCSR_BSS_TYPE_ANY:
4328 			break;
4329 
4330 		case eCSR_BSS_TYPE_INFRASTRUCTURE:
4331 			if (!csr_is_infra_bss_desc(pSirBssDesc))
4332 				fMatch = false;
4333 			break;
4334 
4335 		case eCSR_BSS_TYPE_IBSS:
4336 		case eCSR_BSS_TYPE_START_IBSS:
4337 			if (!csr_is_ibss_bss_desc(pSirBssDesc))
4338 				fMatch = false;
4339 
4340 			break;
4341 		default:
4342 			fMatch = false;
4343 			break;
4344 		}
4345 	} while (0);
4346 
4347 	return fMatch;
4348 }
4349 
4350 static bool csr_is_capabilities_match(tpAniSirGlobal pMac, eCsrRoamBssType bssType,
4351 				      tSirBssDescription *pSirBssDesc)
4352 {
4353 	return csr_is_bss_type_caps_match(bssType, pSirBssDesc);
4354 }
4355 
4356 static bool csr_is_specific_channel_match(tpAniSirGlobal pMac,
4357 					  tSirBssDescription *pSirBssDesc,
4358 					  uint8_t Channel)
4359 {
4360 	bool fMatch = true;
4361 
4362 	do {
4363 		/* if the channel is ANY, then always match... */
4364 		if (eCSR_OPERATING_CHANNEL_ANY == Channel)
4365 			break;
4366 		if (Channel == pSirBssDesc->channelId)
4367 			break;
4368 
4369 		/* didn't match anything.. so return NO match */
4370 		fMatch = false;
4371 
4372 	} while (0);
4373 
4374 	return fMatch;
4375 }
4376 
4377 static bool csr_is_channel_band_match(tpAniSirGlobal pMac, uint8_t channelId,
4378 			       tSirBssDescription *pSirBssDesc)
4379 {
4380 	bool fMatch = true;
4381 
4382 	do {
4383 		/* if the profile says Any channel AND the global settings says ANY channel, then we */
4384 		/* always match... */
4385 		if (eCSR_OPERATING_CHANNEL_ANY == channelId)
4386 			break;
4387 
4388 		if (eCSR_OPERATING_CHANNEL_ANY != channelId) {
4389 			fMatch =
4390 				csr_is_specific_channel_match(pMac, pSirBssDesc,
4391 							      channelId);
4392 		}
4393 
4394 	} while (0);
4395 
4396 	return fMatch;
4397 }
4398 
4399 /**
4400  * csr_is_aggregate_rate_supported() - to check if aggregate rate is supported
4401  * @mac_ctx: pointer to mac context
4402  * @rate: A rate in units of 500kbps
4403  *
4404  *
4405  * The rate encoding  is just as in 802.11  Information Elements, except
4406  * that the high bit is \em  not interpreted as indicating a Basic Rate,
4407  * and proprietary rates are allowed, too.
4408  *
4409  * Note  that if the  adapter's dot11Mode  is g,  we don't  restrict the
4410  * rates.  According to hwReadEepromParameters, this will happen when:
4411  * ... the  card is  configured for ALL  bands through  the property
4412  * page.  If this occurs, and the card is not an ABG card ,then this
4413  * code  is  setting the  dot11Mode  to  assume  the mode  that  the
4414  * hardware can support.   For example, if the card  is an 11BG card
4415  * and we  are configured to support  ALL bands, then  we change the
4416  * dot11Mode  to 11g  because  ALL in  this  case is  only what  the
4417  * hardware can support.
4418  *
4419  * Return: true if  the adapter is currently capable of supporting this rate
4420  */
4421 
4422 static bool csr_is_aggregate_rate_supported(tpAniSirGlobal mac_ctx,
4423 			uint16_t rate)
4424 {
4425 	bool supported = false;
4426 	uint16_t idx, new_rate;
4427 
4428 	/* In case basic rate flag is set */
4429 	new_rate = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
4430 	if (eCSR_CFG_DOT11_MODE_11A ==
4431 			mac_ctx->roam.configParam.uCfgDot11Mode) {
4432 		switch (new_rate) {
4433 		case eCsrSuppRate_6Mbps:
4434 		case eCsrSuppRate_9Mbps:
4435 		case eCsrSuppRate_12Mbps:
4436 		case eCsrSuppRate_18Mbps:
4437 		case eCsrSuppRate_24Mbps:
4438 		case eCsrSuppRate_36Mbps:
4439 		case eCsrSuppRate_48Mbps:
4440 		case eCsrSuppRate_54Mbps:
4441 			supported = true;
4442 			break;
4443 		default:
4444 			supported = false;
4445 			break;
4446 		}
4447 
4448 	} else if (eCSR_CFG_DOT11_MODE_11B ==
4449 		   mac_ctx->roam.configParam.uCfgDot11Mode) {
4450 		switch (new_rate) {
4451 		case eCsrSuppRate_1Mbps:
4452 		case eCsrSuppRate_2Mbps:
4453 		case eCsrSuppRate_5_5Mbps:
4454 		case eCsrSuppRate_11Mbps:
4455 			supported = true;
4456 			break;
4457 		default:
4458 			supported = false;
4459 			break;
4460 		}
4461 	} else if (!mac_ctx->roam.configParam.ProprietaryRatesEnabled) {
4462 
4463 		switch (new_rate) {
4464 		case eCsrSuppRate_1Mbps:
4465 		case eCsrSuppRate_2Mbps:
4466 		case eCsrSuppRate_5_5Mbps:
4467 		case eCsrSuppRate_6Mbps:
4468 		case eCsrSuppRate_9Mbps:
4469 		case eCsrSuppRate_11Mbps:
4470 		case eCsrSuppRate_12Mbps:
4471 		case eCsrSuppRate_18Mbps:
4472 		case eCsrSuppRate_24Mbps:
4473 		case eCsrSuppRate_36Mbps:
4474 		case eCsrSuppRate_48Mbps:
4475 		case eCsrSuppRate_54Mbps:
4476 			supported = true;
4477 			break;
4478 		default:
4479 			supported = false;
4480 			break;
4481 		}
4482 	} else if (eCsrSuppRate_1Mbps == new_rate ||
4483 			eCsrSuppRate_2Mbps == new_rate ||
4484 			eCsrSuppRate_5_5Mbps == new_rate ||
4485 			eCsrSuppRate_11Mbps == new_rate) {
4486 			supported = true;
4487 	} else {
4488 		idx = 0x1;
4489 
4490 		switch (new_rate) {
4491 		case eCsrSuppRate_6Mbps:
4492 			supported = g_phy_rates_suppt[0][idx];
4493 			break;
4494 		case eCsrSuppRate_9Mbps:
4495 			supported = g_phy_rates_suppt[1][idx];
4496 			break;
4497 		case eCsrSuppRate_12Mbps:
4498 			supported = g_phy_rates_suppt[2][idx];
4499 			break;
4500 		case eCsrSuppRate_18Mbps:
4501 			supported = g_phy_rates_suppt[3][idx];
4502 			break;
4503 		case eCsrSuppRate_20Mbps:
4504 			supported = g_phy_rates_suppt[4][idx];
4505 			break;
4506 		case eCsrSuppRate_24Mbps:
4507 			supported = g_phy_rates_suppt[5][idx];
4508 			break;
4509 		case eCsrSuppRate_36Mbps:
4510 			supported = g_phy_rates_suppt[6][idx];
4511 			break;
4512 		case eCsrSuppRate_40Mbps:
4513 			supported = g_phy_rates_suppt[7][idx];
4514 			break;
4515 		case eCsrSuppRate_42Mbps:
4516 			supported = g_phy_rates_suppt[8][idx];
4517 			break;
4518 		case eCsrSuppRate_48Mbps:
4519 			supported = g_phy_rates_suppt[9][idx];
4520 			break;
4521 		case eCsrSuppRate_54Mbps:
4522 			supported = g_phy_rates_suppt[10][idx];
4523 			break;
4524 		case eCsrSuppRate_72Mbps:
4525 			supported = g_phy_rates_suppt[11][idx];
4526 			break;
4527 		case eCsrSuppRate_80Mbps:
4528 			supported = g_phy_rates_suppt[12][idx];
4529 			break;
4530 		case eCsrSuppRate_84Mbps:
4531 			supported = g_phy_rates_suppt[13][idx];
4532 			break;
4533 		case eCsrSuppRate_96Mbps:
4534 			supported = g_phy_rates_suppt[14][idx];
4535 			break;
4536 		case eCsrSuppRate_108Mbps:
4537 			supported = g_phy_rates_suppt[15][idx];
4538 			break;
4539 		case eCsrSuppRate_120Mbps:
4540 			supported = g_phy_rates_suppt[16][idx];
4541 			break;
4542 		case eCsrSuppRate_126Mbps:
4543 			supported = g_phy_rates_suppt[17][idx];
4544 			break;
4545 		case eCsrSuppRate_144Mbps:
4546 			supported = g_phy_rates_suppt[18][idx];
4547 			break;
4548 		case eCsrSuppRate_160Mbps:
4549 			supported = g_phy_rates_suppt[19][idx];
4550 			break;
4551 		case eCsrSuppRate_168Mbps:
4552 			supported = g_phy_rates_suppt[20][idx];
4553 			break;
4554 		case eCsrSuppRate_192Mbps:
4555 			supported = g_phy_rates_suppt[21][idx];
4556 			break;
4557 		case eCsrSuppRate_216Mbps:
4558 			supported = g_phy_rates_suppt[22][idx];
4559 			break;
4560 		case eCsrSuppRate_240Mbps:
4561 			supported = g_phy_rates_suppt[23][idx];
4562 			break;
4563 		default:
4564 			supported = false;
4565 			break;
4566 		}
4567 	}
4568 	return supported;
4569 }
4570 
4571 /**
4572  * csr_is_rate_set_match() - to check if rate set is matching
4573  * @mac_ctx: pointer to mac context
4574  * @bss_supported_rates: supported rates of BSS
4575  * @bss_ext_supp_rates: extended rates of bss
4576  *
4577  * This routine is to checke if rate set is matched or no
4578  *
4579  * Return: bool
4580  */
4581 static bool csr_is_rate_set_match(tpAniSirGlobal mac_ctx,
4582 				  tDot11fIESuppRates *bss_supported_rates,
4583 				  tDot11fIEExtSuppRates *bss_ext_supp_rates)
4584 {
4585 	bool match = true;
4586 	uint32_t i;
4587 
4588 	/*
4589 	 * Validate that all of the Basic rates advertised in the Bss
4590 	 * description are supported
4591 	 */
4592 	if (bss_supported_rates) {
4593 		for (i = 0; i < bss_supported_rates->num_rates; i++) {
4594 			if (!CSR_IS_BASIC_RATE(bss_supported_rates->rates[i]))
4595 				continue;
4596 			if (!csr_is_aggregate_rate_supported(mac_ctx,
4597 					bss_supported_rates->rates[i])) {
4598 				match = false;
4599 				break;
4600 			}
4601 		}
4602 	}
4603 	if (match && bss_ext_supp_rates) {
4604 		for (i = 0; i < bss_ext_supp_rates->num_rates; i++) {
4605 			if (!CSR_IS_BASIC_RATE(bss_ext_supp_rates->rates[i]))
4606 				continue;
4607 			if (!csr_is_aggregate_rate_supported(mac_ctx,
4608 					bss_ext_supp_rates->rates[i])) {
4609 				match = false;
4610 				break;
4611 			}
4612 		}
4613 	}
4614 	return match;
4615 }
4616 
4617 /**
4618  * csr_match_bss() - to compare the bss
4619  * @hal: pointer to hal context
4620  * @bss_descr: pointer bss description
4621  * @filter: scan filter
4622  * @neg_auth: negotiated auth
4623  * @neg_uc: negotiated for unicast
4624  * @neg_mc: negotiated for multicast
4625  * @ie_dblptr: double pointer to IE
4626  *
4627  * This routine will be called to match the bss
4628  * If caller want to get the *ie_dblptr allocated by this function,
4629  * pass in *ie_dblptr = NULL
4630  *
4631  * Return: bool
4632  */
4633 bool csr_match_bss(tHalHandle hal, tSirBssDescription *bss_descr,
4634 		   tCsrScanResultFilter *filter, eCsrAuthType *neg_auth,
4635 		   eCsrEncryptionType *neg_uc, eCsrEncryptionType *neg_mc,
4636 		   tDot11fBeaconIEs **ie_dblptr)
4637 {
4638 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4639 	bool rc = false, check, blacklist_check;
4640 	uint32_t i;
4641 	tDot11fBeaconIEs *ie_ptr = NULL;
4642 	uint8_t *pb;
4643 	struct roam_ext_params *roam_params;
4644 	uint8_t *p2p_macaddr = NULL;
4645 
4646 	roam_params = &mac_ctx->roam.configParam.roam_params;
4647 	if ((NULL == ie_dblptr) || (*ie_dblptr) == NULL) {
4648 		/* If no IEs passed in, get our own. */
4649 		if (!QDF_IS_STATUS_SUCCESS(
4650 			csr_get_parsed_bss_description_ies(mac_ctx,
4651 				bss_descr, &ie_ptr))) {
4652 			goto end;
4653 		}
4654 	} else {
4655 		/* Save the one pass in for local use */
4656 		ie_ptr = *ie_dblptr;
4657 	}
4658 
4659 	/* Check if caller wants P2P */
4660 	check = (!filter->p2pResult || ie_ptr->P2PBeaconProbeRes.present);
4661 	if (!check)
4662 		goto end;
4663 
4664 	/* Check for Blacklist BSSID's and avoid connections */
4665 	blacklist_check = false;
4666 	for (i = 0; i < roam_params->num_bssid_avoid_list; i++) {
4667 		if (qdf_is_macaddr_equal((struct qdf_mac_addr *)
4668 					&roam_params->bssid_avoid_list[i],
4669 				(struct qdf_mac_addr *)bss_descr->bssId)) {
4670 			blacklist_check = true;
4671 			break;
4672 		}
4673 	}
4674 	if (blacklist_check) {
4675 		sms_log(mac_ctx, LOGE,
4676 			FL("Don't Attempt connect to blacklist bssid"));
4677 		goto end;
4678 	}
4679 
4680 	if (ie_ptr->SSID.present) {
4681 		for (i = 0; i < filter->SSIDs.numOfSSIDs; i++) {
4682 			check = csr_is_ssid_match(mac_ctx,
4683 					filter->SSIDs.SSIDList[i].SSID.ssId,
4684 					filter->SSIDs.SSIDList[i].SSID.length,
4685 					ie_ptr->SSID.ssid,
4686 					ie_ptr->SSID.num_ssid, true);
4687 			if (check)
4688 				break;
4689 		}
4690 		if (!check)
4691 			goto end;
4692 	}
4693 	check = true;
4694 	p2p_macaddr = ie_ptr->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress;
4695 	for (i = 0; i < filter->BSSIDs.numOfBSSIDs; i++) {
4696 		check = csr_is_bssid_match(mac_ctx,
4697 				(struct qdf_mac_addr *)&filter->BSSIDs.bssid[i],
4698 				(struct qdf_mac_addr *)bss_descr->bssId);
4699 		if (check)
4700 			break;
4701 
4702 		if (filter->p2pResult && ie_ptr->P2PBeaconProbeRes.present) {
4703 			check = csr_is_bssid_match(mac_ctx,
4704 					(struct qdf_mac_addr *)
4705 						&filter->BSSIDs.bssid[i],
4706 					(struct qdf_mac_addr *)p2p_macaddr);
4707 			if (check)
4708 				break;
4709 		}
4710 	}
4711 	if (!check)
4712 		goto end;
4713 
4714 	check = true;
4715 	for (i = 0; i < filter->ChannelInfo.numOfChannels; i++) {
4716 		check = csr_is_channel_band_match(mac_ctx,
4717 				filter->ChannelInfo.ChannelList[i], bss_descr);
4718 		if (check)
4719 			break;
4720 	}
4721 	if (!check)
4722 		goto end;
4723 	/* If this is for measurement filtering */
4724 	if (filter->fMeasurement) {
4725 		rc = true;
4726 		goto end;
4727 	}
4728 	if (!csr_is_phy_mode_match(mac_ctx, filter->phyMode, bss_descr,
4729 			NULL, NULL, ie_ptr))
4730 		goto end;
4731 
4732 #ifdef WLAN_FEATURE_11W
4733 	if ((!filter->bWPSAssociation) && (!filter->bOSENAssociation) &&
4734 			!csr_is_security_match(mac_ctx, &filter->authType,
4735 				&filter->EncryptionType,
4736 				&filter->mcEncryptionType,
4737 				&filter->MFPEnabled,
4738 				&filter->MFPRequired,
4739 				&filter->MFPCapable,
4740 				bss_descr, ie_ptr, neg_auth,
4741 				neg_uc, neg_mc))
4742 #else
4743 	if ((!filter->bWPSAssociation) && (!filter->bOSENAssociation) &&
4744 			!csr_is_security_match(mac_ctx, &filter->authType,
4745 				&filter->EncryptionType,
4746 				&filter->mcEncryptionType,
4747 				NULL, NULL, NULL,
4748 				bss_descr, ie_ptr, neg_auth,
4749 				neg_uc, neg_mc))
4750 #endif
4751 		goto end;
4752 	if (!csr_is_capabilities_match(mac_ctx, filter->BSSType, bss_descr))
4753 		goto end;
4754 	if (!csr_is_rate_set_match(mac_ctx, &ie_ptr->SuppRates,
4755 			&ie_ptr->ExtSuppRates))
4756 		goto end;
4757 	if ((eCsrRoamWmmQbssOnly == mac_ctx->roam.configParam.WMMSupportMode)
4758 			&& !CSR_IS_QOS_BSS(ie_ptr))
4759 		goto end;
4760 	/*
4761 	 * Check country. check even when pb is NULL because we may
4762 	 * want to make sure
4763 	 */
4764 	pb = (filter->countryCode[0]) ? (filter->countryCode) : NULL;
4765 	check = csr_match_country_code(mac_ctx, pb, ie_ptr);
4766 	if (!check)
4767 		goto end;
4768 
4769 	if (filter->MDID.mdiePresent && csr_roam_is11r_assoc(mac_ctx,
4770 			mac_ctx->roam.roamSession->sessionId)) {
4771 		if (bss_descr->mdiePresent) {
4772 			if (filter->MDID.mobilityDomain !=
4773 					(bss_descr->mdie[1] << 8 |
4774 						bss_descr->mdie[0]))
4775 				goto end;
4776 		} else {
4777 			goto end;
4778 		}
4779 	}
4780 	rc = true;
4781 
4782 end:
4783 	if (ie_dblptr)
4784 		*ie_dblptr = ie_ptr;
4785 	else if (ie_ptr)
4786 		qdf_mem_free(ie_ptr);
4787 	return rc;
4788 }
4789 
4790 static bool csr_match_connected_bss_security(tpAniSirGlobal pMac,
4791 					     tCsrRoamConnectedProfile *pProfile,
4792 					     tSirBssDescription *pBssDesc,
4793 					     tDot11fBeaconIEs *pIes)
4794 {
4795 	tCsrEncryptionList ucEncryptionList, mcEncryptionList;
4796 	tCsrAuthList authList;
4797 
4798 	ucEncryptionList.numEntries = 1;
4799 	ucEncryptionList.encryptionType[0] = pProfile->EncryptionType;
4800 
4801 	mcEncryptionList.numEntries = 1;
4802 	mcEncryptionList.encryptionType[0] = pProfile->mcEncryptionType;
4803 
4804 	authList.numEntries = 1;
4805 	authList.authType[0] = pProfile->AuthType;
4806 
4807 #ifdef WLAN_FEATURE_11W
4808 	return csr_is_security_match(pMac, &authList, &ucEncryptionList,
4809 					&mcEncryptionList,
4810 					&pProfile->MFPEnabled,
4811 					&pProfile->MFPRequired,
4812 					&pProfile->MFPCapable,
4813 					pBssDesc, pIes, NULL, NULL, NULL);
4814 #else
4815 	return csr_is_security_match(pMac, &authList, &ucEncryptionList,
4816 				      &mcEncryptionList, NULL, NULL, NULL,
4817 				      pBssDesc, pIes, NULL, NULL, NULL);
4818 #endif
4819 
4820 }
4821 
4822 bool csr_match_bss_to_connect_profile(tHalHandle hHal,
4823 				      tCsrRoamConnectedProfile *pProfile,
4824 				      tSirBssDescription *pBssDesc,
4825 				      tDot11fBeaconIEs *pIes)
4826 {
4827 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4828 	bool fRC = false, fCheck;
4829 	tDot11fBeaconIEs *pIesLocal = pIes;
4830 
4831 	do {
4832 		if (!pIes) {
4833 			if (!QDF_IS_STATUS_SUCCESS
4834 				    (csr_get_parsed_bss_description_ies
4835 					    (pMac, pBssDesc, &pIesLocal))) {
4836 				break;
4837 			}
4838 		}
4839 		fCheck = true;
4840 		if (pIesLocal->SSID.present) {
4841 			bool fCheckSsid = false;
4842 			if (pProfile->SSID.length) {
4843 				fCheckSsid = true;
4844 			}
4845 			fCheck =
4846 				csr_is_ssid_match(pMac, pProfile->SSID.ssId,
4847 						  pProfile->SSID.length,
4848 						  pIesLocal->SSID.ssid,
4849 						  pIesLocal->SSID.num_ssid,
4850 						  fCheckSsid);
4851 			if (!fCheck)
4852 				break;
4853 		}
4854 		if (!csr_match_connected_bss_security
4855 			    (pMac, pProfile, pBssDesc, pIesLocal))
4856 			break;
4857 		if (!csr_is_capabilities_match(pMac, pProfile->BSSType, pBssDesc))
4858 			break;
4859 		if (!csr_is_rate_set_match
4860 			    (pMac, &pIesLocal->SuppRates, &pIesLocal->ExtSuppRates))
4861 			break;
4862 		fCheck =
4863 			csr_is_channel_band_match(pMac, pProfile->operationChannel,
4864 						  pBssDesc);
4865 		if (!fCheck)
4866 			break;
4867 
4868 		fRC = true;
4869 
4870 	} while (0);
4871 
4872 	if (!pIes && pIesLocal) {
4873 		/* locally allocated */
4874 		qdf_mem_free(pIesLocal);
4875 	}
4876 
4877 	return fRC;
4878 }
4879 
4880 void csr_add_rate_bitmap(uint8_t rate, uint16_t *pRateBitmap)
4881 {
4882 	uint16_t rateBitmap;
4883 	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
4884 	rateBitmap = *pRateBitmap;
4885 	switch (n) {
4886 	case SIR_MAC_RATE_1:
4887 		rateBitmap |= SIR_MAC_RATE_1_BITMAP;
4888 		break;
4889 	case SIR_MAC_RATE_2:
4890 		rateBitmap |= SIR_MAC_RATE_2_BITMAP;
4891 		break;
4892 	case SIR_MAC_RATE_5_5:
4893 		rateBitmap |= SIR_MAC_RATE_5_5_BITMAP;
4894 		break;
4895 	case SIR_MAC_RATE_11:
4896 		rateBitmap |= SIR_MAC_RATE_11_BITMAP;
4897 		break;
4898 	case SIR_MAC_RATE_6:
4899 		rateBitmap |= SIR_MAC_RATE_6_BITMAP;
4900 		break;
4901 	case SIR_MAC_RATE_9:
4902 		rateBitmap |= SIR_MAC_RATE_9_BITMAP;
4903 		break;
4904 	case SIR_MAC_RATE_12:
4905 		rateBitmap |= SIR_MAC_RATE_12_BITMAP;
4906 		break;
4907 	case SIR_MAC_RATE_18:
4908 		rateBitmap |= SIR_MAC_RATE_18_BITMAP;
4909 		break;
4910 	case SIR_MAC_RATE_24:
4911 		rateBitmap |= SIR_MAC_RATE_24_BITMAP;
4912 		break;
4913 	case SIR_MAC_RATE_36:
4914 		rateBitmap |= SIR_MAC_RATE_36_BITMAP;
4915 		break;
4916 	case SIR_MAC_RATE_48:
4917 		rateBitmap |= SIR_MAC_RATE_48_BITMAP;
4918 		break;
4919 	case SIR_MAC_RATE_54:
4920 		rateBitmap |= SIR_MAC_RATE_54_BITMAP;
4921 		break;
4922 	}
4923 	*pRateBitmap = rateBitmap;
4924 }
4925 
4926 bool csr_check_rate_bitmap(uint8_t rate, uint16_t rateBitmap)
4927 {
4928 	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
4929 
4930 	switch (n) {
4931 	case SIR_MAC_RATE_1:
4932 		rateBitmap &= SIR_MAC_RATE_1_BITMAP;
4933 		break;
4934 	case SIR_MAC_RATE_2:
4935 		rateBitmap &= SIR_MAC_RATE_2_BITMAP;
4936 		break;
4937 	case SIR_MAC_RATE_5_5:
4938 		rateBitmap &= SIR_MAC_RATE_5_5_BITMAP;
4939 		break;
4940 	case SIR_MAC_RATE_11:
4941 		rateBitmap &= SIR_MAC_RATE_11_BITMAP;
4942 		break;
4943 	case SIR_MAC_RATE_6:
4944 		rateBitmap &= SIR_MAC_RATE_6_BITMAP;
4945 		break;
4946 	case SIR_MAC_RATE_9:
4947 		rateBitmap &= SIR_MAC_RATE_9_BITMAP;
4948 		break;
4949 	case SIR_MAC_RATE_12:
4950 		rateBitmap &= SIR_MAC_RATE_12_BITMAP;
4951 		break;
4952 	case SIR_MAC_RATE_18:
4953 		rateBitmap &= SIR_MAC_RATE_18_BITMAP;
4954 		break;
4955 	case SIR_MAC_RATE_24:
4956 		rateBitmap &= SIR_MAC_RATE_24_BITMAP;
4957 		break;
4958 	case SIR_MAC_RATE_36:
4959 		rateBitmap &= SIR_MAC_RATE_36_BITMAP;
4960 		break;
4961 	case SIR_MAC_RATE_48:
4962 		rateBitmap &= SIR_MAC_RATE_48_BITMAP;
4963 		break;
4964 	case SIR_MAC_RATE_54:
4965 		rateBitmap &= SIR_MAC_RATE_54_BITMAP;
4966 		break;
4967 	}
4968 	return !!rateBitmap;
4969 }
4970 
4971 bool csr_rates_is_dot11_rate_supported(tHalHandle hHal, uint8_t rate)
4972 {
4973 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4974 	uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
4975 
4976 	return csr_is_aggregate_rate_supported(pMac, n);
4977 }
4978 
4979 static uint16_t csr_rates_mac_prop_to_dot11(uint16_t Rate)
4980 {
4981 	uint16_t ConvertedRate = Rate;
4982 
4983 	switch (Rate) {
4984 	case SIR_MAC_RATE_1:
4985 		ConvertedRate = 2;
4986 		break;
4987 	case SIR_MAC_RATE_2:
4988 		ConvertedRate = 4;
4989 		break;
4990 	case SIR_MAC_RATE_5_5:
4991 		ConvertedRate = 11;
4992 		break;
4993 	case SIR_MAC_RATE_11:
4994 		ConvertedRate = 22;
4995 		break;
4996 
4997 	case SIR_MAC_RATE_6:
4998 		ConvertedRate = 12;
4999 		break;
5000 	case SIR_MAC_RATE_9:
5001 		ConvertedRate = 18;
5002 		break;
5003 	case SIR_MAC_RATE_12:
5004 		ConvertedRate = 24;
5005 		break;
5006 	case SIR_MAC_RATE_18:
5007 		ConvertedRate = 36;
5008 		break;
5009 	case SIR_MAC_RATE_24:
5010 		ConvertedRate = 48;
5011 		break;
5012 	case SIR_MAC_RATE_36:
5013 		ConvertedRate = 72;
5014 		break;
5015 	case SIR_MAC_RATE_42:
5016 		ConvertedRate = 84;
5017 		break;
5018 	case SIR_MAC_RATE_48:
5019 		ConvertedRate = 96;
5020 		break;
5021 	case SIR_MAC_RATE_54:
5022 		ConvertedRate = 108;
5023 		break;
5024 
5025 	case SIR_MAC_RATE_72:
5026 		ConvertedRate = 144;
5027 		break;
5028 	case SIR_MAC_RATE_84:
5029 		ConvertedRate = 168;
5030 		break;
5031 	case SIR_MAC_RATE_96:
5032 		ConvertedRate = 192;
5033 		break;
5034 	case SIR_MAC_RATE_108:
5035 		ConvertedRate = 216;
5036 		break;
5037 	case SIR_MAC_RATE_126:
5038 		ConvertedRate = 252;
5039 		break;
5040 	case SIR_MAC_RATE_144:
5041 		ConvertedRate = 288;
5042 		break;
5043 	case SIR_MAC_RATE_168:
5044 		ConvertedRate = 336;
5045 		break;
5046 	case SIR_MAC_RATE_192:
5047 		ConvertedRate = 384;
5048 		break;
5049 	case SIR_MAC_RATE_216:
5050 		ConvertedRate = 432;
5051 		break;
5052 	case SIR_MAC_RATE_240:
5053 		ConvertedRate = 480;
5054 		break;
5055 
5056 	case 0xff:
5057 		ConvertedRate = 0;
5058 		break;
5059 	}
5060 
5061 	return ConvertedRate;
5062 }
5063 
5064 uint16_t csr_rates_find_best_rate(tSirMacRateSet *pSuppRates,
5065 				  tSirMacRateSet *pExtRates,
5066 				  tSirMacPropRateSet *pPropRates)
5067 {
5068 	uint8_t i;
5069 	uint16_t nBest;
5070 
5071 	nBest = pSuppRates->rate[0] & (~CSR_DOT11_BASIC_RATE_MASK);
5072 
5073 	if (pSuppRates->numRates > SIR_MAC_RATESET_EID_MAX) {
5074 		pSuppRates->numRates = SIR_MAC_RATESET_EID_MAX;
5075 	}
5076 
5077 	for (i = 1U; i < pSuppRates->numRates; ++i) {
5078 		nBest =
5079 			(uint16_t) CSR_MAX(nBest,
5080 					   pSuppRates->
5081 					   rate[i] & (~CSR_DOT11_BASIC_RATE_MASK));
5082 	}
5083 
5084 	if (NULL != pExtRates) {
5085 		for (i = 0U; i < pExtRates->numRates; ++i) {
5086 			nBest =
5087 				(uint16_t) CSR_MAX(nBest,
5088 						   pExtRates->
5089 						   rate[i] &
5090 						   (~CSR_DOT11_BASIC_RATE_MASK));
5091 		}
5092 	}
5093 
5094 	if (NULL != pPropRates) {
5095 		for (i = 0U; i < pPropRates->numPropRates; ++i) {
5096 			nBest =
5097 				(uint16_t) CSR_MAX(nBest,
5098 						   csr_rates_mac_prop_to_dot11
5099 							   (pPropRates->propRate[i]));
5100 		}
5101 	}
5102 
5103 	return nBest;
5104 }
5105 
5106 void csr_release_profile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile)
5107 {
5108 	if (pProfile) {
5109 		if (pProfile->BSSIDs.bssid) {
5110 			qdf_mem_free(pProfile->BSSIDs.bssid);
5111 			pProfile->BSSIDs.bssid = NULL;
5112 		}
5113 		if (pProfile->SSIDs.SSIDList) {
5114 			qdf_mem_free(pProfile->SSIDs.SSIDList);
5115 			pProfile->SSIDs.SSIDList = NULL;
5116 		}
5117 		if (pProfile->pWPAReqIE) {
5118 			qdf_mem_free(pProfile->pWPAReqIE);
5119 			pProfile->pWPAReqIE = NULL;
5120 		}
5121 		if (pProfile->pRSNReqIE) {
5122 			qdf_mem_free(pProfile->pRSNReqIE);
5123 			pProfile->pRSNReqIE = NULL;
5124 		}
5125 #ifdef FEATURE_WLAN_WAPI
5126 		if (pProfile->pWAPIReqIE) {
5127 			qdf_mem_free(pProfile->pWAPIReqIE);
5128 			pProfile->pWAPIReqIE = NULL;
5129 		}
5130 #endif /* FEATURE_WLAN_WAPI */
5131 
5132 		if (pProfile->pAddIEScan) {
5133 			qdf_mem_free(pProfile->pAddIEScan);
5134 			pProfile->pAddIEScan = NULL;
5135 		}
5136 
5137 		if (pProfile->pAddIEAssoc) {
5138 			qdf_mem_free(pProfile->pAddIEAssoc);
5139 			pProfile->pAddIEAssoc = NULL;
5140 		}
5141 		if (pProfile->ChannelInfo.ChannelList) {
5142 			qdf_mem_free(pProfile->ChannelInfo.ChannelList);
5143 			pProfile->ChannelInfo.ChannelList = NULL;
5144 		}
5145 		qdf_mem_set(pProfile, sizeof(tCsrRoamProfile), 0);
5146 	}
5147 }
5148 
5149 void csr_free_scan_filter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
5150 {
5151 	if (pScanFilter->BSSIDs.bssid) {
5152 		qdf_mem_free(pScanFilter->BSSIDs.bssid);
5153 		pScanFilter->BSSIDs.bssid = NULL;
5154 	}
5155 	if (pScanFilter->ChannelInfo.ChannelList) {
5156 		qdf_mem_free(pScanFilter->ChannelInfo.ChannelList);
5157 		pScanFilter->ChannelInfo.ChannelList = NULL;
5158 	}
5159 	if (pScanFilter->SSIDs.SSIDList) {
5160 		qdf_mem_free(pScanFilter->SSIDs.SSIDList);
5161 		pScanFilter->SSIDs.SSIDList = NULL;
5162 	}
5163 }
5164 
5165 void csr_free_roam_profile(tpAniSirGlobal pMac, uint32_t sessionId)
5166 {
5167 	tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
5168 
5169 	if (pSession->pCurRoamProfile) {
5170 		csr_release_profile(pMac, pSession->pCurRoamProfile);
5171 		qdf_mem_free(pSession->pCurRoamProfile);
5172 		pSession->pCurRoamProfile = NULL;
5173 	}
5174 }
5175 
5176 void csr_free_connect_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId)
5177 {
5178 	tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
5179 
5180 	if (pSession->pConnectBssDesc) {
5181 		qdf_mem_free(pSession->pConnectBssDesc);
5182 		pSession->pConnectBssDesc = NULL;
5183 	}
5184 }
5185 
5186 tSirResultCodes csr_get_disassoc_rsp_status_code(tSirSmeDisassocRsp *
5187 						 pSmeDisassocRsp)
5188 {
5189 	uint8_t *pBuffer = (uint8_t *) pSmeDisassocRsp;
5190 	uint32_t ret;
5191 
5192 	pBuffer += (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(tSirMacAddr));
5193 	/* tSirResultCodes is an enum, assuming is 32bit */
5194 	/* If we cannot make this assumption, use copymemory */
5195 	qdf_get_u32(pBuffer, &ret);
5196 
5197 	return (tSirResultCodes) ret;
5198 }
5199 
5200 tSirResultCodes csr_get_de_auth_rsp_status_code(tSirSmeDeauthRsp *pSmeRsp)
5201 {
5202 	uint8_t *pBuffer = (uint8_t *) pSmeRsp;
5203 	uint32_t ret;
5204 
5205 	pBuffer +=
5206 		(sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint8_t) +
5207 		 sizeof(uint16_t));
5208 	/* tSirResultCodes is an enum, assuming is 32bit */
5209 	/* If we cannot make this assumption, use copymemory */
5210 	qdf_get_u32(pBuffer, &ret);
5211 
5212 	return (tSirResultCodes) ret;
5213 }
5214 
5215 tSirScanType csr_get_scan_type(tpAniSirGlobal pMac, uint8_t chnId)
5216 {
5217 	tSirScanType scanType = eSIR_PASSIVE_SCAN;
5218 	enum channel_state channelEnabledType;
5219 
5220 	channelEnabledType = cds_get_channel_state(chnId);
5221 	if (CHANNEL_STATE_ENABLE == channelEnabledType) {
5222 		scanType = eSIR_ACTIVE_SCAN;
5223 	}
5224 	return scanType;
5225 }
5226 
5227 uint8_t csr_to_upper(uint8_t ch)
5228 {
5229 	uint8_t chOut;
5230 
5231 	if (ch >= 'a' && ch <= 'z') {
5232 		chOut = ch - 'a' + 'A';
5233 	} else {
5234 		chOut = ch;
5235 	}
5236 	return chOut;
5237 }
5238 
5239 tSirBssType csr_translate_bsstype_to_mac_type(eCsrRoamBssType csrtype)
5240 {
5241 	tSirBssType ret;
5242 
5243 	switch (csrtype) {
5244 	case eCSR_BSS_TYPE_INFRASTRUCTURE:
5245 		ret = eSIR_INFRASTRUCTURE_MODE;
5246 		break;
5247 	case eCSR_BSS_TYPE_IBSS:
5248 	case eCSR_BSS_TYPE_START_IBSS:
5249 		ret = eSIR_IBSS_MODE;
5250 		break;
5251 	case eCSR_BSS_TYPE_INFRA_AP:
5252 		ret = eSIR_INFRA_AP_MODE;
5253 		break;
5254 	case eCSR_BSS_TYPE_NDI:
5255 		ret = eSIR_NDI_MODE;
5256 		break;
5257 	case eCSR_BSS_TYPE_ANY:
5258 	default:
5259 		ret = eSIR_AUTO_MODE;
5260 		break;
5261 	}
5262 
5263 	return ret;
5264 }
5265 
5266 /* This function use the parameters to decide the CFG value. */
5267 /* CSR never sets WNI_CFG_DOT11_MODE_ALL to the CFG */
5268 /* So PE should not see WNI_CFG_DOT11_MODE_ALL when it gets the CFG value */
5269 eCsrCfgDot11Mode csr_get_cfg_dot11_mode_from_csr_phy_mode(tCsrRoamProfile *pProfile,
5270 							  eCsrPhyMode phyMode,
5271 							  bool fProprietary)
5272 {
5273 	uint32_t cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
5274 
5275 	switch (phyMode) {
5276 	case eCSR_DOT11_MODE_11a:
5277 		cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
5278 		break;
5279 	case eCSR_DOT11_MODE_11b:
5280 	case eCSR_DOT11_MODE_11b_ONLY:
5281 		cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
5282 		break;
5283 	case eCSR_DOT11_MODE_11g:
5284 	case eCSR_DOT11_MODE_11g_ONLY:
5285 		if (pProfile && (CSR_IS_INFRA_AP(pProfile))
5286 		    && (phyMode == eCSR_DOT11_MODE_11g_ONLY))
5287 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G_ONLY;
5288 		else
5289 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
5290 		break;
5291 	case eCSR_DOT11_MODE_11n:
5292 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
5293 		break;
5294 	case eCSR_DOT11_MODE_11n_ONLY:
5295 		if (pProfile && CSR_IS_INFRA_AP(pProfile))
5296 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N_ONLY;
5297 		else
5298 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
5299 		break;
5300 	case eCSR_DOT11_MODE_abg:
5301 		cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
5302 		break;
5303 	case eCSR_DOT11_MODE_AUTO:
5304 		cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
5305 		break;
5306 
5307 	case eCSR_DOT11_MODE_11ac:
5308 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
5309 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
5310 		} else {
5311 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
5312 		}
5313 		break;
5314 	case eCSR_DOT11_MODE_11ac_ONLY:
5315 		if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
5316 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
5317 		} else {
5318 			cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
5319 		}
5320 		break;
5321 	default:
5322 		/* No need to assign anything here */
5323 		break;
5324 	}
5325 
5326 	return cfgDot11Mode;
5327 }
5328 
5329 QDF_STATUS csr_get_regulatory_domain_for_country(tpAniSirGlobal pMac,
5330 						 uint8_t *pCountry,
5331 						 v_REGDOMAIN_t *pDomainId,
5332 						 enum country_src source)
5333 {
5334 	QDF_STATUS status = QDF_STATUS_E_INVAL;
5335 	QDF_STATUS qdf_status;
5336 	uint8_t countryCode[CDS_COUNTRY_CODE_LEN + 1];
5337 	v_REGDOMAIN_t domainId;
5338 
5339 	if (pCountry) {
5340 		countryCode[0] = pCountry[0];
5341 		countryCode[1] = pCountry[1];
5342 		qdf_status = cds_get_reg_domain_from_country_code(&domainId,
5343 								  countryCode,
5344 								  source);
5345 
5346 		if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
5347 			if (pDomainId) {
5348 				*pDomainId = domainId;
5349 			}
5350 			status = QDF_STATUS_SUCCESS;
5351 		} else {
5352 			sms_log(pMac, LOGW,
5353 				FL
5354 					(" Couldn't find domain for country code  %c%c"),
5355 				pCountry[0], pCountry[1]);
5356 			status = QDF_STATUS_E_INVAL;
5357 		}
5358 	}
5359 
5360 	return status;
5361 }
5362 
5363 /* To check whether a country code matches the one in the IE */
5364 /* Only check the first two characters, ignoring in/outdoor */
5365 /* pCountry -- caller allocated buffer contain the country code that is checking against */
5366 /* the one in pIes. It can be NULL. */
5367 /* caller must provide pIes, it cannot be NULL */
5368 /* This function always return true if 11d support is not turned on. */
5369 bool csr_match_country_code(tpAniSirGlobal pMac, uint8_t *pCountry,
5370 			    tDot11fBeaconIEs *pIes)
5371 {
5372 	bool fRet = true;
5373 
5374 	do {
5375 		if (!csr_is11d_supported(pMac)) {
5376 			break;
5377 		}
5378 		if (!pIes) {
5379 			sms_log(pMac, LOGE, FL("  No IEs"));
5380 			break;
5381 		}
5382 
5383 		if (pCountry) {
5384 			uint32_t i;
5385 
5386 			if (!pIes->Country.present) {
5387 				fRet = false;
5388 				break;
5389 			}
5390 			/* Convert the CountryCode characters to upper */
5391 			for (i = 0; i < WNI_CFG_COUNTRY_CODE_LEN - 1; i++) {
5392 				pCountry[i] = csr_to_upper(pCountry[i]);
5393 			}
5394 			if (qdf_mem_cmp(pIes->Country.country, pCountry,
5395 					     WNI_CFG_COUNTRY_CODE_LEN - 1)) {
5396 				fRet = false;
5397 				break;
5398 			}
5399 		}
5400 	} while (0);
5401 
5402 	return fRet;
5403 }
5404 
5405 QDF_STATUS csr_get_modify_profile_fields(tpAniSirGlobal pMac, uint32_t sessionId,
5406 					 tCsrRoamModifyProfileFields *
5407 					 pModifyProfileFields)
5408 {
5409 
5410 	if (!pModifyProfileFields) {
5411 		return QDF_STATUS_E_FAILURE;
5412 	}
5413 
5414 	qdf_mem_copy(pModifyProfileFields,
5415 		     &pMac->roam.roamSession[sessionId].connectedProfile.
5416 		     modifyProfileFields, sizeof(tCsrRoamModifyProfileFields));
5417 
5418 	return QDF_STATUS_SUCCESS;
5419 }
5420 
5421 QDF_STATUS csr_set_modify_profile_fields(tpAniSirGlobal pMac, uint32_t sessionId,
5422 					 tCsrRoamModifyProfileFields *
5423 					 pModifyProfileFields)
5424 {
5425 	tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
5426 
5427 	qdf_mem_copy(&pSession->connectedProfile.modifyProfileFields,
5428 		     pModifyProfileFields, sizeof(tCsrRoamModifyProfileFields));
5429 
5430 	return QDF_STATUS_SUCCESS;
5431 }
5432 
5433 
5434 bool csr_is_set_key_allowed(tpAniSirGlobal pMac, uint32_t sessionId)
5435 {
5436 	bool fRet = true;
5437 	tCsrRoamSession *pSession;
5438 
5439 	pSession = CSR_GET_SESSION(pMac, sessionId);
5440 
5441 	/*
5442 	 * This condition is not working for infra state. When infra is in
5443 	 * not-connected state the pSession->pCurRoamProfile is NULL, this
5444 	 * function returns true, that is incorrect.
5445 	 * Since SAP requires to set key without any BSS started, it needs
5446 	 * this condition to be met. In other words, this function is useless.
5447 	 * The current work-around is to process setcontext_rsp no matter
5448 	 * what the state is.
5449 	 */
5450 	sms_log(pMac, LOG2,
5451 		FL(" is not what it intends to. Must be revisit or removed"));
5452 	if ((NULL == pSession)
5453 	    || (csr_is_conn_state_disconnected(pMac, sessionId)
5454 		&& (pSession->pCurRoamProfile != NULL)
5455 		&& (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))))
5456 	    ) {
5457 		fRet = false;
5458 	}
5459 
5460 	return fRet;
5461 }
5462 
5463 /* no need to acquire lock for this basic function */
5464 uint16_t sme_chn_to_freq(uint8_t chanNum)
5465 {
5466 	int i;
5467 
5468 	for (i = 0; i < NUM_CHANNELS; i++) {
5469 		if (CDS_CHANNEL_NUM(i) == chanNum)
5470 			return CDS_CHANNEL_FREQ(i);
5471 	}
5472 
5473 	return 0;
5474 }
5475 
5476 /* Disconnect all active sessions by sending disassoc. This is mainly used to disconnect the remaining session when we
5477  * transition from concurrent sessions to a single session. The use case is Infra STA and wifi direct multiple sessions are up and
5478  * P2P session is removed. The Infra STA session remains and should resume BMPS if BMPS is enabled by default. However, there
5479  * are some issues seen with BMPS resume during this transition and this is a workaround which will allow the Infra STA session to
5480  * disconnect and auto connect back and enter BMPS this giving the same effect as resuming BMPS
5481  */
5482 
5483 /* Remove this code once SLM_Sessionization is supported */
5484 /* BMPS_WORKAROUND_NOT_NEEDED */
5485 void csr_disconnect_all_active_sessions(tpAniSirGlobal pMac)
5486 {
5487 	uint8_t i;
5488 
5489 	/* Disconnect all the active sessions */
5490 	for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
5491 		if (CSR_IS_SESSION_VALID(pMac, i)
5492 		    && !csr_is_conn_state_disconnected(pMac, i)) {
5493 			csr_roam_disconnect_internal(pMac, i,
5494 						     eCSR_DISCONNECT_REASON_UNSPECIFIED);
5495 		}
5496 	}
5497 }
5498 
5499 bool csr_is_channel_present_in_list(uint8_t *pChannelList,
5500 				    int numChannels, uint8_t channel)
5501 {
5502 	int i = 0;
5503 
5504 	/* Check for NULL pointer */
5505 	if (!pChannelList || (numChannels == 0)) {
5506 		return false;
5507 	}
5508 	/* Look for the channel in the list */
5509 	for (i = 0; (i < numChannels) &&
5510 	     (i < WNI_CFG_VALID_CHANNEL_LIST_LEN); i++) {
5511 		if (pChannelList[i] == channel)
5512 			return true;
5513 	}
5514 
5515 	return false;
5516 }
5517 
5518 /**
5519  * sme_request_type_to_string(): converts scan request enum to string.
5520  * @request_type: scan request type enum.
5521  *
5522  * Return: Printable string for request_type
5523  */
5524 const char *sme_request_type_to_string(const uint8_t request_type)
5525 {
5526 	switch (request_type) {
5527 	CASE_RETURN_STRING(eCSR_SCAN_REQUEST_11D_SCAN);
5528 	CASE_RETURN_STRING(eCSR_SCAN_REQUEST_FULL_SCAN);
5529 	CASE_RETURN_STRING(eCSR_SCAN_IDLE_MODE_SCAN);
5530 	CASE_RETURN_STRING(eCSR_SCAN_HO_PROBE_SCAN);
5531 	CASE_RETURN_STRING(eCSR_SCAN_P2P_DISCOVERY);
5532 	CASE_RETURN_STRING(eCSR_SCAN_SOFTAP_CHANNEL_RANGE);
5533 	CASE_RETURN_STRING(eCSR_SCAN_P2P_FIND_PEER);
5534 	default:
5535 		return "Unknown Scan Request Type";
5536 	}
5537 }
5538 
5539 /**
5540  * sme_bsstype_to_string() - converts bss type to string.
5541  * @bss_type: bss type enum
5542  *
5543  * Return: printable string for bss type
5544  */
5545 const char *sme_bss_type_to_string(const uint8_t bss_type)
5546 {
5547 	switch (bss_type) {
5548 	CASE_RETURN_STRING(eCSR_BSS_TYPE_INFRASTRUCTURE);
5549 	CASE_RETURN_STRING(eCSR_BSS_TYPE_INFRA_AP);
5550 	CASE_RETURN_STRING(eCSR_BSS_TYPE_IBSS);
5551 	CASE_RETURN_STRING(eCSR_BSS_TYPE_START_IBSS);
5552 	CASE_RETURN_STRING(eCSR_BSS_TYPE_ANY);
5553 	default:
5554 		return "unknown bss type";
5555 	}
5556 }
5557 
5558 /**
5559  * sme_scantype_to_string() - converts scan type to string.
5560  * @scan_type: scan type enum
5561  *
5562  * Return: printable string for scan type
5563  */
5564 const char *sme_scan_type_to_string(const uint8_t scan_type)
5565 {
5566 	switch (scan_type) {
5567 	CASE_RETURN_STRING(eSIR_PASSIVE_SCAN);
5568 	CASE_RETURN_STRING(eSIR_ACTIVE_SCAN);
5569 	CASE_RETURN_STRING(eSIR_BEACON_TABLE);
5570 	default:
5571 		return "unknown scan type";
5572 	}
5573 }
5574 
5575 QDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList,
5576 					 int numChannels, uint8_t channel)
5577 {
5578 	int i = 0;
5579 
5580 	/* Check for NULL pointer */
5581 	if (!pChannelList)
5582 		return QDF_STATUS_E_NULL_VALUE;
5583 
5584 	/* Make room for the addition.  (Start moving from the back.) */
5585 	for (i = numChannels; i > 0; i--) {
5586 		pChannelList[i] = pChannelList[i - 1];
5587 	}
5588 
5589 	/* Now add the NEW channel...at the front */
5590 	pChannelList[0] = channel;
5591 
5592 	return QDF_STATUS_SUCCESS;
5593 }
5594 #ifdef FEATURE_WLAN_DIAG_SUPPORT
5595 /**
5596  * csr_diag_event_report() - send PE diag event
5597  * @pmac:        pointer to global MAC context.
5598  * @event_typev: sub event type for DIAG event.
5599  * @status:      status of the event
5600  * @reasoncode:  reasoncode for the given status
5601  *
5602  * This function is called to send diag event
5603  *
5604  * Return:   NA
5605  */
5606 void csr_diag_event_report(tpAniSirGlobal pmac, uint16_t event_type,
5607 			   uint16_t status, uint16_t reasoncode)
5608 {
5609 	WLAN_HOST_DIAG_EVENT_DEF(diag_event, host_event_wlan_pe_payload_type);
5610 
5611 	qdf_mem_zero(&diag_event, sizeof(host_event_wlan_pe_payload_type));
5612 
5613 	/* diag_event.bssid is already all zeroes */
5614 	diag_event.sme_state = sme_get_lim_sme_state(pmac);
5615 	diag_event.mlm_state = sme_get_lim_mlm_state(pmac);
5616 	diag_event.event_type = event_type;
5617 	diag_event.status = status;
5618 	diag_event.reason_code = reasoncode;
5619 
5620 	WLAN_HOST_DIAG_EVENT_REPORT(&diag_event, EVENT_WLAN_PE);
5621 	return;
5622 }
5623 #endif
5624 
5625 /**
5626  * csr_wait_for_connection_update() - Wait for hw mode update
5627  * @mac: Pointer to the MAC context
5628  * @do_release_reacquire_lock: Indicates whether release and
5629  * re-acquisition of SME global lock is required.
5630  *
5631  * Waits for CONNECTION_UPDATE_TIMEOUT time so that the
5632  * hw mode update can get processed.
5633  *
5634  * Return: True if the wait was successful, false otherwise
5635  */
5636 bool csr_wait_for_connection_update(tpAniSirGlobal mac,
5637 		bool do_release_reacquire_lock)
5638 {
5639 	QDF_STATUS status, ret;
5640 
5641 	if (do_release_reacquire_lock == true) {
5642 		ret = sme_release_global_lock(&mac->sme);
5643 		if (!QDF_IS_STATUS_SUCCESS(ret)) {
5644 			cds_err("lock release fail %d", ret);
5645 			return false;
5646 		}
5647 	}
5648 
5649 	status = qdf_wait_for_connection_update();
5650 
5651 	if (do_release_reacquire_lock == true) {
5652 		ret = sme_acquire_global_lock(&mac->sme);
5653 		if (!QDF_IS_STATUS_SUCCESS(ret)) {
5654 			cds_err("lock acquire fail %d", ret);
5655 			return false;
5656 		}
5657 	}
5658 
5659 	if (!QDF_IS_STATUS_SUCCESS(status)) {
5660 		cds_err("wait for event failed");
5661 		return false;
5662 	}
5663 
5664 	return true;
5665 }
5666 
5667 /**
5668  * csr_get_session_persona() - get persona of a session
5669  * @pmac: pointer to global MAC context
5670  * @session_id: session id
5671  *
5672  * This function is to return the persona of a session
5673  *
5674  * Reture: enum tQDF_ADAPTER_MODE persona
5675  */
5676 enum tQDF_ADAPTER_MODE csr_get_session_persona(tpAniSirGlobal pmac,
5677 						uint32_t session_id)
5678 {
5679 	tCsrRoamSession *session = NULL;
5680 
5681 	session = CSR_GET_SESSION(pmac, session_id);
5682 	if (NULL == session || NULL == session->pCurRoamProfile)
5683 		return QDF_MAX_NO_OF_MODE;
5684 
5685 	return session->pCurRoamProfile->csrPersona;
5686 }
5687 
5688 /**
5689  * csr_is_ndi_started() - function to check if NDI is started
5690  * @mac_ctx: handle to mac context
5691  * @session_id: session identifier
5692  *
5693  * returns: true if NDI is started, false otherwise
5694  */
5695 bool csr_is_ndi_started(tpAniSirGlobal mac_ctx, uint32_t session_id)
5696 {
5697 	tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
5698 	if (!session)
5699 		return false;
5700 
5701 	return eCSR_CONNECT_STATE_TYPE_NDI_STARTED == session->connectState;
5702 }
5703