xref: /wlan-dirver/qcacld-3.0/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c (revision 6147c58dff00905c59dc4f432e6487aa8d278bb6)
1 /*
2  * Copyright (c) 2012-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  * This file lim_send_sme_rspMessages.cc contains the functions
30  * for sending SME response/notification messages to applications
31  * above MAC software.
32  * Author:        Chandra Modumudi
33  * Date:          02/13/02
34  * History:-
35  * Date           Modified by    Modification Information
36  * --------------------------------------------------------------------
37  */
38 
39 #include "qdf_types.h"
40 #include "wni_api.h"
41 #include "sir_common.h"
42 #include "ani_global.h"
43 
44 #include "wni_cfg.h"
45 #include "sys_def.h"
46 #include "cfg_api.h"
47 
48 #include "sch_api.h"
49 #include "utils_api.h"
50 #include "lim_utils.h"
51 #include "lim_security_utils.h"
52 #include "lim_ser_des_utils.h"
53 #include "lim_send_sme_rsp_messages.h"
54 #include "lim_ibss_peer_mgmt.h"
55 #include "lim_session_utils.h"
56 #include "lim_types.h"
57 #include "sir_api.h"
58 #include "cds_regdomain.h"
59 #include "lim_send_messages.h"
60 #include "nan_datapath.h"
61 #include "lim_assoc_utils.h"
62 
63 static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
64 	tpPESession session_entry, tSirResultCodes result_code,
65 	tpSirSmeJoinRsp sme_join_rsp);
66 
67 /**
68  * lim_send_sme_rsp() - Send Response to upper layers
69  * @mac_ctx:          Pointer to Global MAC structure
70  * @msg_type:         Indicates message type
71  * @result_code:       Indicates the result of previously issued
72  *                    eWNI_SME_msg_type_REQ message
73  *
74  * This function is called by lim_process_sme_req_messages() to send
75  * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP
76  * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC
77  * Software.
78  *
79  * Return: None
80  */
81 
82 void
83 lim_send_sme_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
84 	 tSirResultCodes result_code, uint8_t sme_session_id,
85 	 uint16_t sme_transaction_id)
86 {
87 	tSirMsgQ msg;
88 	tSirSmeRsp *sme_rsp;
89 
90 	lim_log(mac_ctx, LOG1, FL("Sending message %s with reasonCode %s"),
91 		lim_msg_str(msg_type), lim_result_code_str(result_code));
92 
93 	sme_rsp = qdf_mem_malloc(sizeof(tSirSmeRsp));
94 	if (NULL == sme_rsp) {
95 		/* Buffer not available. Log error */
96 		QDF_TRACE(QDF_MODULE_ID_PE, LOGP,
97 			FL("call to AllocateMemory failed for eWNI_SME_*_RSP"));
98 		return;
99 	}
100 
101 	sme_rsp->messageType = msg_type;
102 	sme_rsp->length = sizeof(tSirSmeRsp);
103 	sme_rsp->statusCode = result_code;
104 
105 	sme_rsp->sessionId = sme_session_id;
106 	sme_rsp->transactionId = sme_transaction_id;
107 
108 	msg.type = msg_type;
109 	msg.bodyptr = sme_rsp;
110 	msg.bodyval = 0;
111 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG,
112 			 sme_session_id, msg.type));
113 
114 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
115 	switch (msg_type) {
116 	case eWNI_SME_STOP_BSS_RSP:
117 		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
118 				NULL, (uint16_t) result_code, 0);
119 		break;
120 	}
121 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
122 	lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
123 }
124 
125 
126 
127 /**
128  * lim_send_sme_roc_rsp() - Send Response to SME
129  * @mac_ctx:          Pointer to Global MAC structure
130  * @status:           Resume link status
131  * @result_code:  Result of the ROC request
132  * @sme_session_id:   SME sesson Id
133  * @scan_id:  Scan Identifier
134  *
135  * This function is called to send ROC rsp
136  * message to SME.
137  *
138  * Return: None
139  */
140 void
141 lim_send_sme_roc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
142 	 tSirResultCodes result_code, uint8_t sme_session_id,
143 	 uint32_t scan_id)
144 {
145 	tSirMsgQ msg;
146 	struct sir_roc_rsp *sme_rsp;
147 
148 	lim_log(mac_ctx, LOG1,
149 		FL("Sending message %s with reasonCode %s scanId %d"),
150 		lim_msg_str(msg_type), lim_result_code_str(result_code),
151 		scan_id);
152 
153 	sme_rsp = qdf_mem_malloc(sizeof(struct sir_roc_rsp));
154 	if (NULL == sme_rsp) {
155 		QDF_TRACE(QDF_MODULE_ID_PE, LOGP,
156 			FL("call to AllocateMemory failed for eWNI_SME_*_RSP"));
157 		return;
158 	}
159 
160 	sme_rsp->message_type = msg_type;
161 	sme_rsp->length = sizeof(struct sir_roc_rsp);
162 	sme_rsp->status = result_code;
163 
164 	sme_rsp->session_id = sme_session_id;
165 	sme_rsp->scan_id = scan_id;
166 
167 	msg.type = msg_type;
168 	msg.bodyptr = sme_rsp;
169 	msg.bodyval = 0;
170 	MTRACE(mac_trace_msg_tx(mac_ctx, sme_session_id, msg.type));
171 	lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
172 }
173 
174 
175 /**
176  * lim_get_max_rate_flags() - Get rate flags
177  * @mac_ctx: Pointer to global MAC structure
178  * @sta_ds: Pointer to station ds structure
179  *
180  * This function is called to get the rate flags for a connection
181  * from the station ds structure depending on the ht and the vht
182  * channel width supported.
183  *
184  * Return: Returns the populated rate_flags
185  */
186 uint32_t lim_get_max_rate_flags(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds)
187 {
188 	uint32_t rate_flags = 0;
189 
190 	if (sta_ds == NULL) {
191 		lim_log(mac_ctx, LOGE, FL("sta_ds is NULL"));
192 		return rate_flags;
193 	}
194 
195 	if (!sta_ds->mlmStaContext.htCapability &&
196 	    !sta_ds->mlmStaContext.vhtCapability) {
197 		rate_flags |= eHAL_TX_RATE_LEGACY;
198 	} else {
199 		if (sta_ds->mlmStaContext.vhtCapability) {
200 			if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ ==
201 				sta_ds->vhtSupportedChannelWidthSet) {
202 				rate_flags |= eHAL_TX_RATE_VHT80;
203 			} else if (WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ ==
204 					sta_ds->vhtSupportedChannelWidthSet) {
205 				if (sta_ds->htSupportedChannelWidthSet)
206 					rate_flags |= eHAL_TX_RATE_VHT40;
207 				else
208 					rate_flags |= eHAL_TX_RATE_VHT20;
209 			}
210 		} else if (sta_ds->mlmStaContext.htCapability) {
211 			if (sta_ds->htSupportedChannelWidthSet)
212 				rate_flags |= eHAL_TX_RATE_HT40;
213 			else
214 				rate_flags |= eHAL_TX_RATE_HT20;
215 		}
216 	}
217 
218 	if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
219 		rate_flags |= eHAL_TX_RATE_SGI;
220 
221 	return rate_flags;
222 }
223 
224 /**
225  * lim_send_sme_join_reassoc_rsp_after_resume() - Send Response to SME
226  * @mac_ctx          Pointer to Global MAC structure
227  * @status           Resume link status
228  * @ctx              context passed while calling resmune link.
229  *                   (join response to be sent)
230  *
231  * This function is called to send Join/Reassoc rsp
232  * message to SME after the resume link.
233  *
234  * Return: None
235  */
236 static void lim_send_sme_join_reassoc_rsp_after_resume(tpAniSirGlobal mac_ctx,
237 	QDF_STATUS status, uint32_t *ctx)
238 {
239 	tSirMsgQ msg;
240 	tpSirSmeJoinRsp sme_join_rsp = (tpSirSmeJoinRsp) ctx;
241 
242 	msg.type = sme_join_rsp->messageType;
243 	msg.bodyptr = sme_join_rsp;
244 	msg.bodyval = 0;
245 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, NO_SESSION, msg.type));
246 	lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
247 }
248 
249 /**
250  * lim_handle_join_rsp_status() - Handle the response.
251  * @mac_ctx:            Pointer to Global MAC structure
252  * @session_entry:      PE Session Info
253  * @result_code:        Indicates the result of previously issued
254  *                      eWNI_SME_msgType_REQ message
255  * @sme_join_rsp        The received response.
256  *
257  * This function will handle both the success and failure status
258  * of the received response.
259  *
260  * Return: None
261  */
262 static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
263 	tpPESession session_entry, tSirResultCodes result_code,
264 	tpSirSmeJoinRsp sme_join_rsp)
265 {
266 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
267 	tSirSmeHTProfile *ht_profile;
268 #endif
269 	if (result_code == eSIR_SME_SUCCESS) {
270 		if (session_entry->beacon != NULL) {
271 			sme_join_rsp->beaconLength = session_entry->bcnLen;
272 			qdf_mem_copy(sme_join_rsp->frames,
273 				session_entry->beacon,
274 				sme_join_rsp->beaconLength);
275 			qdf_mem_free(session_entry->beacon);
276 			session_entry->beacon = NULL;
277 			session_entry->bcnLen = 0;
278 			lim_log(mac_ctx, LOG1, FL("Beacon=%d"),
279 				sme_join_rsp->beaconLength);
280 		}
281 		if (session_entry->assocReq != NULL) {
282 			sme_join_rsp->assocReqLength =
283 				session_entry->assocReqLen;
284 			qdf_mem_copy(sme_join_rsp->frames +
285 				sme_join_rsp->beaconLength,
286 				session_entry->assocReq,
287 				sme_join_rsp->assocReqLength);
288 			qdf_mem_free(session_entry->assocReq);
289 			session_entry->assocReq = NULL;
290 			session_entry->assocReqLen = 0;
291 			lim_log(mac_ctx,
292 				LOG1, FL("AssocReq=%d"),
293 				sme_join_rsp->assocReqLength);
294 		}
295 		if (session_entry->assocRsp != NULL) {
296 			sme_join_rsp->assocRspLength =
297 				session_entry->assocRspLen;
298 			qdf_mem_copy(sme_join_rsp->frames +
299 				sme_join_rsp->beaconLength +
300 				sme_join_rsp->assocReqLength,
301 				session_entry->assocRsp,
302 				sme_join_rsp->assocRspLength);
303 			qdf_mem_free(session_entry->assocRsp);
304 			session_entry->assocRsp = NULL;
305 			session_entry->assocRspLen = 0;
306 		}
307 		if (session_entry->ricData != NULL) {
308 			sme_join_rsp->parsedRicRspLen =
309 				session_entry->RICDataLen;
310 			qdf_mem_copy(sme_join_rsp->frames +
311 				sme_join_rsp->beaconLength +
312 				sme_join_rsp->assocReqLength +
313 				sme_join_rsp->assocRspLength,
314 				session_entry->ricData,
315 				sme_join_rsp->parsedRicRspLen);
316 			qdf_mem_free(session_entry->ricData);
317 			session_entry->ricData = NULL;
318 			session_entry->RICDataLen = 0;
319 			lim_log(mac_ctx, LOG1, FL("RicLength=%d"),
320 				sme_join_rsp->parsedRicRspLen);
321 		}
322 #ifdef FEATURE_WLAN_ESE
323 		if (session_entry->tspecIes != NULL) {
324 			sme_join_rsp->tspecIeLen =
325 				session_entry->tspecLen;
326 			qdf_mem_copy(sme_join_rsp->frames +
327 				sme_join_rsp->beaconLength +
328 				sme_join_rsp->assocReqLength +
329 				sme_join_rsp->assocRspLength +
330 				sme_join_rsp->parsedRicRspLen,
331 				session_entry->tspecIes,
332 				sme_join_rsp->tspecIeLen);
333 			qdf_mem_free(session_entry->tspecIes);
334 			session_entry->tspecIes = NULL;
335 			session_entry->tspecLen = 0;
336 			lim_log(mac_ctx, LOG1, FL("ESE-TspecLen=%d"),
337 				sme_join_rsp->tspecIeLen);
338 		}
339 #endif
340 		sme_join_rsp->aid = session_entry->limAID;
341 		lim_log(mac_ctx, LOG1, FL("AssocRsp=%d"),
342 			sme_join_rsp->assocRspLength);
343 		sme_join_rsp->vht_channel_width =
344 			session_entry->ch_width;
345 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
346 		if (session_entry->cc_switch_mode !=
347 				QDF_MCC_TO_SCC_SWITCH_DISABLE) {
348 			ht_profile = &sme_join_rsp->HTProfile;
349 			ht_profile->htSupportedChannelWidthSet =
350 				session_entry->htSupportedChannelWidthSet;
351 			ht_profile->htRecommendedTxWidthSet =
352 				session_entry->htRecommendedTxWidthSet;
353 			ht_profile->htSecondaryChannelOffset =
354 				session_entry->htSecondaryChannelOffset;
355 			ht_profile->dot11mode = session_entry->dot11mode;
356 			ht_profile->htCapability = session_entry->htCapability;
357 			ht_profile->vhtCapability =
358 				session_entry->vhtCapability;
359 			ht_profile->apCenterChan = session_entry->ch_center_freq_seg0;
360 			ht_profile->apChanWidth = session_entry->ch_width;
361 		}
362 #endif
363 	} else {
364 		if (session_entry->beacon != NULL) {
365 			qdf_mem_free(session_entry->beacon);
366 			session_entry->beacon = NULL;
367 			session_entry->bcnLen = 0;
368 		}
369 		if (session_entry->assocReq != NULL) {
370 			qdf_mem_free(session_entry->assocReq);
371 			session_entry->assocReq = NULL;
372 			session_entry->assocReqLen = 0;
373 		}
374 		if (session_entry->assocRsp != NULL) {
375 			qdf_mem_free(session_entry->assocRsp);
376 			session_entry->assocRsp = NULL;
377 			session_entry->assocRspLen = 0;
378 		}
379 		if (session_entry->ricData != NULL) {
380 			qdf_mem_free(session_entry->ricData);
381 			session_entry->ricData = NULL;
382 			session_entry->RICDataLen = 0;
383 		}
384 #ifdef FEATURE_WLAN_ESE
385 		if (session_entry->tspecIes != NULL) {
386 			qdf_mem_free(session_entry->tspecIes);
387 			session_entry->tspecIes = NULL;
388 			session_entry->tspecLen = 0;
389 		}
390 #endif
391 	}
392 }
393 
394 /**
395  * lim_add_bss_info() - copy data from session entry to join rsp
396  * @sta_ds: Station dph entry
397  * @sme_join_rsp: Join response buffer to be filled up
398  *
399  * Return: None
400  */
401 static void lim_add_bss_info(tpDphHashNode sta_ds, tpSirSmeJoinRsp sme_join_rsp)
402 {
403 	struct parsed_ies *parsed_ies = &sta_ds->parsed_ies;
404 
405 	if (parsed_ies->hs20vendor_ie.present)
406 		sme_join_rsp->hs20vendor_ie = parsed_ies->hs20vendor_ie;
407 	if (parsed_ies->vht_caps.present)
408 		sme_join_rsp->vht_caps = parsed_ies->vht_caps;
409 	if (parsed_ies->ht_caps.present)
410 		sme_join_rsp->ht_caps = parsed_ies->ht_caps;
411 	if (parsed_ies->ht_operation.present)
412 		sme_join_rsp->ht_operation = parsed_ies->ht_operation;
413 	if (parsed_ies->vht_operation.present)
414 		sme_join_rsp->vht_operation = parsed_ies->vht_operation;
415 }
416 
417 /**
418  * lim_send_sme_join_reassoc_rsp() - Send Response to Upper Layers
419  * @mac_ctx:            Pointer to Global MAC structure
420  * @msg_type:           Indicates message type
421  * @result_code:        Indicates the result of previously issued
422  *                      eWNI_SME_msgType_REQ message
423  * @prot_status_code:   Protocol Status Code
424  * @session_entry:      PE Session Info
425  * @sme_session_id:     SME Session ID
426  * @sme_transaction_id: SME Transaction ID
427  *
428  * This function is called by lim_process_sme_req_messages() to send
429  * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications
430  * above MAC Software.
431  *
432  * Return: None
433  */
434 
435 void
436 lim_send_sme_join_reassoc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
437 	tSirResultCodes result_code, uint16_t prot_status_code,
438 	tpPESession session_entry, uint8_t sme_session_id,
439 	uint16_t sme_transaction_id)
440 {
441 	tpSirSmeJoinRsp sme_join_rsp;
442 	uint32_t rsp_len;
443 	tpDphHashNode sta_ds = NULL;
444 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
445 	if (msg_type == eWNI_SME_REASSOC_RSP)
446 		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_RSP_EVENT,
447 			session_entry, (uint16_t) result_code, 0);
448 	else
449 		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_RSP_EVENT,
450 			session_entry, (uint16_t) result_code, 0);
451 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
452 
453 	lim_log(mac_ctx, LOG1, FL("Sending message %s with reasonCode %s"),
454 		lim_msg_str(msg_type), lim_result_code_str(result_code));
455 
456 	if (session_entry == NULL) {
457 		rsp_len = sizeof(tSirSmeJoinRsp);
458 		sme_join_rsp = qdf_mem_malloc(rsp_len);
459 		if (NULL == sme_join_rsp) {
460 			lim_log(mac_ctx, LOGP,
461 				FL("Mem Alloc fail - JOIN/REASSOC_RSP"));
462 			return;
463 		}
464 
465 		qdf_mem_set((uint8_t *) sme_join_rsp, rsp_len, 0);
466 		sme_join_rsp->beaconLength = 0;
467 		sme_join_rsp->assocReqLength = 0;
468 		sme_join_rsp->assocRspLength = 0;
469 	} else {
470 		rsp_len = session_entry->assocReqLen +
471 			session_entry->assocRspLen + session_entry->bcnLen +
472 			session_entry->RICDataLen +
473 #ifdef FEATURE_WLAN_ESE
474 			session_entry->tspecLen +
475 #endif
476 			sizeof(tSirSmeJoinRsp) - sizeof(uint8_t);
477 		sme_join_rsp = qdf_mem_malloc(rsp_len);
478 		if (NULL == sme_join_rsp) {
479 			lim_log(mac_ctx, LOGP,
480 				FL("MemAlloc fail - JOIN/REASSOC_RSP"));
481 			return;
482 		}
483 		qdf_mem_set((uint8_t *) sme_join_rsp, rsp_len, 0);
484 		if (result_code == eSIR_SME_SUCCESS) {
485 			sta_ds = dph_get_hash_entry(mac_ctx,
486 				DPH_STA_HASH_INDEX_PEER,
487 				&session_entry->dph.dphHashTable);
488 			if (sta_ds == NULL) {
489 				lim_log(mac_ctx, LOGE,
490 					FL("Get Self Sta Entry fail"));
491 			} else {
492 				/* Pass the peer's staId */
493 				sme_join_rsp->staId = sta_ds->staIndex;
494 				sme_join_rsp->ucastSig =
495 					sta_ds->ucUcastSig;
496 				sme_join_rsp->bcastSig =
497 					sta_ds->ucBcastSig;
498 				sme_join_rsp->timingMeasCap =
499 					sta_ds->timingMeasCap;
500 #ifdef FEATURE_WLAN_TDLS
501 				sme_join_rsp->tdls_prohibited =
502 					session_entry->tdls_prohibited;
503 				sme_join_rsp->tdls_chan_swit_prohibited =
504 				   session_entry->tdls_chan_swit_prohibited;
505 #endif
506 				sme_join_rsp->nss = sta_ds->nss;
507 				sme_join_rsp->max_rate_flags =
508 					lim_get_max_rate_flags(mac_ctx, sta_ds);
509 				lim_add_bss_info(sta_ds, sme_join_rsp);
510 			}
511 		}
512 		sme_join_rsp->beaconLength = 0;
513 		sme_join_rsp->assocReqLength = 0;
514 		sme_join_rsp->assocRspLength = 0;
515 		sme_join_rsp->parsedRicRspLen = 0;
516 #ifdef FEATURE_WLAN_ESE
517 		sme_join_rsp->tspecIeLen = 0;
518 #endif
519 		lim_handle_join_rsp_status(mac_ctx, session_entry, result_code,
520 			sme_join_rsp);
521 
522 		/* Send supported NSS 1x1 to SME */
523 		sme_join_rsp->supported_nss_1x1 =
524 			session_entry->supported_nss_1x1;
525 		lim_log(mac_ctx, LOG1,
526 		       FL("SME Join Rsp is supported NSS 1X1: %d"),
527 		       sme_join_rsp->supported_nss_1x1);
528 	}
529 
530 	sme_join_rsp->messageType = msg_type;
531 	sme_join_rsp->length = (uint16_t) rsp_len;
532 	sme_join_rsp->statusCode = result_code;
533 	sme_join_rsp->protStatusCode = prot_status_code;
534 
535 	sme_join_rsp->sessionId = sme_session_id;
536 	sme_join_rsp->transactionId = sme_transaction_id;
537 
538 	lim_send_sme_join_reassoc_rsp_after_resume(mac_ctx, QDF_STATUS_SUCCESS,
539 			(uint32_t *)sme_join_rsp);
540 }
541 
542 /**
543  * lim_send_sme_start_bss_rsp()
544  *
545  ***FUNCTION:
546  * This function is called to send eWNI_SME_START_BSS_RSP
547  * message to applications above MAC Software.
548  *
549  ***PARAMS:
550  *
551  ***LOGIC:
552  *
553  ***ASSUMPTIONS:
554  * NA
555  *
556  ***NOTE:
557  * NA
558  *
559  * @param pMac         Pointer to Global MAC structure
560  * @param msgType      Indicates message type
561  * @param resultCode   Indicates the result of previously issued
562  *                     eWNI_SME_msgType_REQ message
563  *
564  * @return None
565  */
566 
567 void
568 lim_send_sme_start_bss_rsp(tpAniSirGlobal pMac,
569 			   uint16_t msgType, tSirResultCodes resultCode,
570 			   tpPESession psessionEntry, uint8_t smesessionId,
571 			   uint16_t smetransactionId)
572 {
573 
574 	uint16_t size = 0;
575 	tSirMsgQ mmhMsg;
576 	tSirSmeStartBssRsp *pSirSmeRsp;
577 	uint16_t ieLen;
578 	uint16_t ieOffset, curLen;
579 
580 	PELOG1(lim_log(pMac, LOG1, FL("Sending message %s with reasonCode %s"),
581 		       lim_msg_str(msgType), lim_result_code_str(resultCode));
582 	       )
583 
584 	size = sizeof(tSirSmeStartBssRsp);
585 
586 	if (psessionEntry == NULL) {
587 		pSirSmeRsp = qdf_mem_malloc(size);
588 		if (NULL == pSirSmeRsp) {
589 			/* / Buffer not available. Log error */
590 			lim_log(pMac, LOGP,
591 				FL
592 					("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP"));
593 			return;
594 		}
595 		qdf_mem_set((uint8_t *) pSirSmeRsp, size, 0);
596 
597 	} else {
598 		/* subtract size of beaconLength + Mac Hdr + Fixed Fields before SSID */
599 		ieOffset = sizeof(tAniBeaconStruct) + SIR_MAC_B_PR_SSID_OFFSET;
600 		ieLen = psessionEntry->schBeaconOffsetBegin
601 			+ psessionEntry->schBeaconOffsetEnd - ieOffset;
602 		/* calculate the memory size to allocate */
603 		size += ieLen;
604 
605 		pSirSmeRsp = qdf_mem_malloc(size);
606 		if (NULL == pSirSmeRsp) {
607 			/* / Buffer not available. Log error */
608 			lim_log(pMac, LOGP,
609 				FL
610 					("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP"));
611 
612 			return;
613 		}
614 		qdf_mem_set((uint8_t *) pSirSmeRsp, size, 0);
615 		size = sizeof(tSirSmeStartBssRsp);
616 		if (resultCode == eSIR_SME_SUCCESS) {
617 
618 			sir_copy_mac_addr(pSirSmeRsp->bssDescription.bssId,
619 					  psessionEntry->bssId);
620 
621 			/* Read beacon interval from session */
622 			pSirSmeRsp->bssDescription.beaconInterval =
623 				(uint16_t) psessionEntry->beaconParams.
624 				beaconInterval;
625 			pSirSmeRsp->bssType = psessionEntry->bssType;
626 
627 			if (cfg_get_capability_info
628 				    (pMac, &pSirSmeRsp->bssDescription.capabilityInfo,
629 				    psessionEntry)
630 			    != eSIR_SUCCESS)
631 				lim_log(pMac, LOGP,
632 					FL
633 						("could not retrieve Capabilities value"));
634 
635 			lim_get_phy_mode(pMac,
636 					 (uint32_t *) &pSirSmeRsp->bssDescription.
637 					 nwType, psessionEntry);
638 
639 			pSirSmeRsp->bssDescription.channelId =
640 				psessionEntry->currentOperChannel;
641 
642 		if (!LIM_IS_NDI_ROLE(psessionEntry)) {
643 			curLen = psessionEntry->schBeaconOffsetBegin - ieOffset;
644 			qdf_mem_copy((uint8_t *) &pSirSmeRsp->bssDescription.
645 				     ieFields,
646 				     psessionEntry->pSchBeaconFrameBegin +
647 				     ieOffset, (uint32_t) curLen);
648 
649 			qdf_mem_copy(((uint8_t *) &pSirSmeRsp->bssDescription.
650 				      ieFields) + curLen,
651 				     psessionEntry->pSchBeaconFrameEnd,
652 				     (uint32_t) psessionEntry->
653 				     schBeaconOffsetEnd);
654 
655 			/* subtracting size of length indicator itself and size of pointer to ieFields */
656 			pSirSmeRsp->bssDescription.length =
657 				sizeof(tSirBssDescription) - sizeof(uint16_t) -
658 				sizeof(uint32_t) + ieLen;
659 			/* This is the size of the message, subtracting the size of the pointer to ieFields */
660 			size += ieLen - sizeof(uint32_t);
661 		}
662 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
663 			if (psessionEntry->cc_switch_mode
664 			    != QDF_MCC_TO_SCC_SWITCH_DISABLE) {
665 				pSirSmeRsp->HTProfile.
666 				htSupportedChannelWidthSet =
667 					psessionEntry->htSupportedChannelWidthSet;
668 				pSirSmeRsp->HTProfile.htRecommendedTxWidthSet =
669 					psessionEntry->htRecommendedTxWidthSet;
670 				pSirSmeRsp->HTProfile.htSecondaryChannelOffset =
671 					psessionEntry->htSecondaryChannelOffset;
672 				pSirSmeRsp->HTProfile.dot11mode =
673 					psessionEntry->dot11mode;
674 				pSirSmeRsp->HTProfile.htCapability =
675 					psessionEntry->htCapability;
676 				pSirSmeRsp->HTProfile.vhtCapability =
677 					psessionEntry->vhtCapability;
678 				pSirSmeRsp->HTProfile.apCenterChan =
679 					psessionEntry->ch_center_freq_seg0;
680 				pSirSmeRsp->HTProfile.apChanWidth =
681 					psessionEntry->ch_width;
682 			}
683 #endif
684 		}
685 	}
686 	pSirSmeRsp->messageType = msgType;
687 	pSirSmeRsp->length = size;
688 
689 	/* Update SME session Id and transaction Id */
690 	pSirSmeRsp->sessionId = smesessionId;
691 	pSirSmeRsp->transactionId = smetransactionId;
692 	pSirSmeRsp->statusCode = resultCode;
693 	if (psessionEntry != NULL)
694 		pSirSmeRsp->staId = psessionEntry->staId;       /* else it will be always zero smeRsp StaID = 0 */
695 
696 	mmhMsg.type = msgType;
697 	mmhMsg.bodyptr = pSirSmeRsp;
698 	mmhMsg.bodyval = 0;
699 	if (psessionEntry == NULL) {
700 		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
701 				 NO_SESSION, mmhMsg.type));
702 	} else {
703 		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
704 				 psessionEntry->peSessionId, mmhMsg.type));
705 	}
706 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
707 	lim_diag_event_report(pMac, WLAN_PE_DIAG_START_BSS_RSP_EVENT,
708 			      psessionEntry, (uint16_t) resultCode, 0);
709 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
710 
711 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
712 } /*** end lim_send_sme_start_bss_rsp() ***/
713 
714 /**
715  * lim_send_sme_scan_rsp() - Send scan response to SME
716  * @pMac:         Pointer to Global MAC structure
717  * @length:       Indicates length of message
718  * @resultCode:   Indicates the result of previously issued
719  *                     eWNI_SME_SCAN_REQ message
720  * @scan_id: scan identifier
721  *
722  * This function is called by lim_process_sme_req_messages() to send
723  * eWNI_SME_SCAN_RSP message to applications above MAC
724  *
725  * return: None
726  */
727 
728 void
729 lim_send_sme_scan_rsp(tpAniSirGlobal pMac, tSirResultCodes resultCode,
730 		uint8_t smesessionId, uint16_t smetranscationId,
731 		uint32_t scan_id)
732 {
733 	lim_post_sme_scan_rsp_message(pMac, resultCode, smesessionId,
734 				smetranscationId, scan_id);
735 }
736 
737 /**
738  * lim_post_sme_scan_rsp_message()
739  *
740  ***FUNCTION:
741  * This function is called by lim_send_sme_scan_rsp() to send
742  * eWNI_SME_SCAN_RSP message with failed result code
743  *
744  ***NOTE:
745  * NA
746  *
747  * @param pMac         Pointer to Global MAC structure
748  * @param length       Indicates length of message
749  * @param resultCode   failed result code
750  *
751  * @return None
752  */
753 
754 void
755 lim_post_sme_scan_rsp_message(tpAniSirGlobal pMac,
756 			tSirResultCodes resultCode, uint8_t smesessionId,
757 			uint16_t smetransactionId,
758 			uint32_t scan_id)
759 {
760 	tpSirSmeScanRsp pSirSmeScanRsp;
761 	tSirMsgQ mmhMsg;
762 
763 	lim_log(pMac, LOG1, FL("send SME_SCAN_RSP (reasonCode %s)."),
764 		lim_result_code_str(resultCode));
765 
766 	pSirSmeScanRsp = qdf_mem_malloc(sizeof(tSirSmeScanRsp));
767 	if (NULL == pSirSmeScanRsp) {
768 		lim_log(pMac, LOGP,
769 			FL("AllocateMemory failed for eWNI_SME_SCAN_RSP"));
770 		return;
771 	}
772 	qdf_mem_set((void *)pSirSmeScanRsp, sizeof(tSirSmeScanRsp), 0);
773 
774 	pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP;
775 	pSirSmeScanRsp->statusCode = resultCode;
776 
777 	/*Update SME session Id and transaction Id */
778 	pSirSmeScanRsp->sessionId = smesessionId;
779 	pSirSmeScanRsp->transcationId = smetransactionId;
780 	pSirSmeScanRsp->scan_id = scan_id;
781 
782 	mmhMsg.type = eWNI_SME_SCAN_RSP;
783 	mmhMsg.bodyptr = pSirSmeScanRsp;
784 	mmhMsg.bodyval = 0;
785 
786 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type));
787 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
788 	lim_diag_event_report(pMac, WLAN_PE_DIAG_SCAN_RSP_EVENT, NULL,
789 			      (uint16_t) resultCode, 0);
790 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
791 
792 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
793 	return;
794 
795 } /*** lim_post_sme_scan_rsp_message ***/
796 
797 void lim_send_sme_disassoc_deauth_ntf(tpAniSirGlobal pMac,
798 				      QDF_STATUS status, uint32_t *pCtx)
799 {
800 	tSirMsgQ mmhMsg;
801 	tSirMsgQ *pMsg = (tSirMsgQ *) pCtx;
802 
803 	mmhMsg.type = pMsg->type;
804 	mmhMsg.bodyptr = pMsg;
805 	mmhMsg.bodyval = 0;
806 
807 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type));
808 
809 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
810 }
811 
812 /**
813  * lim_send_sme_disassoc_ntf()
814  *
815  ***FUNCTION:
816  * This function is called by limProcessSmeMessages() to send
817  * eWNI_SME_DISASSOC_RSP/IND message to host
818  *
819  ***PARAMS:
820  *
821  ***LOGIC:
822  *
823  ***ASSUMPTIONS:
824  * NA
825  *
826  ***NOTE:
827  * This function is used for sending eWNI_SME_DISASSOC_CNF,
828  * or eWNI_SME_DISASSOC_IND to host depending on
829  * disassociation trigger.
830  *
831  * @param peerMacAddr       Indicates the peer MAC addr to which
832  *                          disassociate was initiated
833  * @param reasonCode        Indicates the reason for Disassociation
834  * @param disassocTrigger   Indicates the trigger for Disassociation
835  * @param aid               Indicates the STAID. This parameter is
836  *                          present only on AP.
837  *
838  * @return None
839  */
840 void
841 lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac,
842 			  tSirMacAddr peerMacAddr,
843 			  tSirResultCodes reasonCode,
844 			  uint16_t disassocTrigger,
845 			  uint16_t aid,
846 			  uint8_t smesessionId,
847 			  uint16_t smetransactionId, tpPESession psessionEntry)
848 {
849 
850 	uint8_t *pBuf;
851 	tSirSmeDisassocRsp *pSirSmeDisassocRsp;
852 	tSirSmeDisassocInd *pSirSmeDisassocInd;
853 	uint32_t *pMsg = NULL;
854 	bool failure = false;
855 	tpPESession session = NULL;
856 	uint16_t i, assoc_id;
857 	tpDphHashNode sta_ds = NULL;
858 
859 	lim_log(pMac, LOG1, FL("Disassoc Ntf with trigger : %d reasonCode: %d"),
860 		disassocTrigger, reasonCode);
861 
862 	switch (disassocTrigger) {
863 	case eLIM_DUPLICATE_ENTRY:
864 		/*
865 		 * Duplicate entry is removed at LIM.
866 		 * Initiate new entry for other session
867 		 */
868 		lim_log(pMac, LOG1,
869 			FL("Rcvd eLIM_DUPLICATE_ENTRY for " MAC_ADDRESS_STR),
870 			MAC_ADDR_ARRAY(peerMacAddr));
871 
872 		for (i = 0; i < pMac->lim.maxBssId; i++) {
873 			if ((&pMac->lim.gpSession[i] != NULL) &&
874 					(pMac->lim.gpSession[i].valid) &&
875 					(pMac->lim.gpSession[i].pePersona ==
876 								QDF_SAP_MODE)) {
877 				/* Find the sta ds entry in another session */
878 				session = &pMac->lim.gpSession[i];
879 				sta_ds = dph_lookup_hash_entry(pMac,
880 						peerMacAddr, &assoc_id,
881 						&session->dph.dphHashTable);
882 			}
883 		}
884 		if (sta_ds
885 #ifdef WLAN_FEATURE_11W
886 			&& (!sta_ds->rmfEnabled)
887 #endif
888 		) {
889 			if (lim_add_sta(pMac, sta_ds, false, session) !=
890 					eSIR_SUCCESS)
891 					lim_log(pMac, LOGE,
892 					FL("could not Add STA with assocId=%d"),
893 					sta_ds->assocId);
894 		}
895 		failure = true;
896 		break;
897 
898 	case eLIM_PEER_ENTITY_DISASSOC:
899 		if (reasonCode != eSIR_SME_STA_NOT_ASSOCIATED) {
900 			failure = true;
901 			goto error;
902 		}
903 
904 	case eLIM_HOST_DISASSOC:
905 		/**
906 		 * Disassociation response due to
907 		 * host triggered disassociation
908 		 */
909 
910 		pSirSmeDisassocRsp = qdf_mem_malloc(sizeof(tSirSmeDisassocRsp));
911 		if (NULL == pSirSmeDisassocRsp) {
912 			/* Log error */
913 			lim_log(pMac, LOGP, FL("Memory allocation failed"));
914 			failure = true;
915 			goto error;
916 		}
917 		lim_log(pMac, LOG1, FL("send eWNI_SME_DISASSOC_RSP with "
918 				       "retCode: %d for " MAC_ADDRESS_STR),
919 			reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
920 		pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP;
921 		pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp);
922 		/* sessionId */
923 		pBuf = (uint8_t *) &pSirSmeDisassocRsp->sessionId;
924 		*pBuf = smesessionId;
925 		pBuf++;
926 
927 		/* transactionId */
928 		lim_copy_u16(pBuf, smetransactionId);
929 		pBuf += sizeof(uint16_t);
930 
931 		/* statusCode */
932 		lim_copy_u32(pBuf, reasonCode);
933 		pBuf += sizeof(tSirResultCodes);
934 
935 		/* peerMacAddr */
936 		qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
937 		pBuf += sizeof(tSirMacAddr);
938 
939 		/* Clear Station Stats */
940 		/* for sta, it is always 1, IBSS is handled at halInitSta */
941 
942 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
943 
944 		lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
945 				      psessionEntry, (uint16_t) reasonCode, 0);
946 #endif
947 		pMsg = (uint32_t *) pSirSmeDisassocRsp;
948 		break;
949 
950 	default:
951 		/**
952 		 * Disassociation indication due to Disassociation
953 		 * frame reception from peer entity or due to
954 		 * loss of link with peer entity.
955 		 */
956 		pSirSmeDisassocInd = qdf_mem_malloc(sizeof(tSirSmeDisassocInd));
957 		if (NULL == pSirSmeDisassocInd) {
958 			/* Log error */
959 			lim_log(pMac, LOGP, FL("Memory allocation failed"));
960 			failure = true;
961 			goto error;
962 		}
963 		lim_log(pMac, LOG1, FL("send eWNI_SME_DISASSOC_IND with "
964 				       "retCode: %d for " MAC_ADDRESS_STR),
965 			reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
966 		pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
967 		pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
968 
969 		/* Update SME session Id and Transaction Id */
970 		pSirSmeDisassocInd->sessionId = smesessionId;
971 		pSirSmeDisassocInd->transactionId = smetransactionId;
972 		pSirSmeDisassocInd->reasonCode = reasonCode;
973 		pBuf = (uint8_t *) &pSirSmeDisassocInd->statusCode;
974 
975 		lim_copy_u32(pBuf, reasonCode);
976 		pBuf += sizeof(tSirResultCodes);
977 
978 		qdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
979 		pBuf += sizeof(tSirMacAddr);
980 
981 		qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
982 
983 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
984 		lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT,
985 				      psessionEntry, (uint16_t) reasonCode, 0);
986 #endif
987 		pMsg = (uint32_t *) pSirSmeDisassocInd;
988 
989 		break;
990 	}
991 
992 error:
993 	/* Delete the PE session Created */
994 	if ((psessionEntry != NULL) && LIM_IS_STA_ROLE(psessionEntry))
995 		pe_delete_session(pMac, psessionEntry);
996 
997 	if (false == failure)
998 		lim_send_sme_disassoc_deauth_ntf(pMac, QDF_STATUS_SUCCESS,
999 						 (uint32_t *) pMsg);
1000 } /*** end lim_send_sme_disassoc_ntf() ***/
1001 
1002 /** -----------------------------------------------------------------
1003    \brief lim_send_sme_disassoc_ind() - sends SME_DISASSOC_IND
1004 
1005    After receiving disassociation frame from peer entity, this
1006    function sends a eWNI_SME_DISASSOC_IND to SME with a specific
1007    reason code.
1008 
1009    \param pMac - global mac structure
1010    \param pStaDs - station dph hash node
1011    \return none
1012    \sa
1013    ----------------------------------------------------------------- */
1014 void
1015 lim_send_sme_disassoc_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
1016 			  tpPESession psessionEntry)
1017 {
1018 	tSirMsgQ mmhMsg;
1019 	tSirSmeDisassocInd *pSirSmeDisassocInd;
1020 
1021 	pSirSmeDisassocInd = qdf_mem_malloc(sizeof(tSirSmeDisassocInd));
1022 	if (NULL == pSirSmeDisassocInd) {
1023 		lim_log(pMac, LOGP,
1024 			FL("AllocateMemory failed for eWNI_SME_DISASSOC_IND"));
1025 		return;
1026 	}
1027 
1028 	pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
1029 	pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
1030 
1031 	pSirSmeDisassocInd->sessionId = psessionEntry->smeSessionId;
1032 	pSirSmeDisassocInd->transactionId = psessionEntry->transactionId;
1033 	pSirSmeDisassocInd->statusCode = eSIR_SME_DEAUTH_STATUS;
1034 	pSirSmeDisassocInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
1035 
1036 	qdf_mem_copy(pSirSmeDisassocInd->bssid.bytes, psessionEntry->bssId,
1037 		     QDF_MAC_ADDR_SIZE);
1038 
1039 	qdf_mem_copy(pSirSmeDisassocInd->peer_macaddr.bytes, pStaDs->staAddr,
1040 		     QDF_MAC_ADDR_SIZE);
1041 
1042 	pSirSmeDisassocInd->staId = pStaDs->staIndex;
1043 
1044 	mmhMsg.type = eWNI_SME_DISASSOC_IND;
1045 	mmhMsg.bodyptr = pSirSmeDisassocInd;
1046 	mmhMsg.bodyval = 0;
1047 
1048 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
1049 			 psessionEntry->peSessionId, mmhMsg.type));
1050 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
1051 	lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, psessionEntry,
1052 			      0, (uint16_t) pStaDs->mlmStaContext.disassocReason);
1053 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1054 
1055 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1056 
1057 } /*** end lim_send_sme_disassoc_ind() ***/
1058 
1059 /** -----------------------------------------------------------------
1060    \brief lim_send_sme_deauth_ind() - sends SME_DEAUTH_IND
1061 
1062    After receiving deauthentication frame from peer entity, this
1063    function sends a eWNI_SME_DEAUTH_IND to SME with a specific
1064    reason code.
1065 
1066    \param pMac - global mac structure
1067    \param pStaDs - station dph hash node
1068    \return none
1069    \sa
1070    ----------------------------------------------------------------- */
1071 void
1072 lim_send_sme_deauth_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
1073 			tpPESession psessionEntry)
1074 {
1075 	tSirMsgQ mmhMsg;
1076 	tSirSmeDeauthInd *pSirSmeDeauthInd;
1077 
1078 	pSirSmeDeauthInd = qdf_mem_malloc(sizeof(tSirSmeDeauthInd));
1079 	if (NULL == pSirSmeDeauthInd) {
1080 		lim_log(pMac, LOGP,
1081 			FL("AllocateMemory failed for eWNI_SME_DEAUTH_IND "));
1082 		return;
1083 	}
1084 
1085 	pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
1086 	pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
1087 
1088 	pSirSmeDeauthInd->sessionId = psessionEntry->smeSessionId;
1089 	pSirSmeDeauthInd->transactionId = psessionEntry->transactionId;
1090 	if (eSIR_INFRA_AP_MODE == psessionEntry->bssType) {
1091 		pSirSmeDeauthInd->statusCode =
1092 			(tSirResultCodes) pStaDs->mlmStaContext.cleanupTrigger;
1093 	} else {
1094 		/* Need to indicatet he reascon code over the air */
1095 		pSirSmeDeauthInd->statusCode =
1096 			(tSirResultCodes) pStaDs->mlmStaContext.disassocReason;
1097 	}
1098 	/* BSSID */
1099 	qdf_mem_copy(pSirSmeDeauthInd->bssid.bytes, psessionEntry->bssId,
1100 		     QDF_MAC_ADDR_SIZE);
1101 	/* peerMacAddr */
1102 	qdf_mem_copy(pSirSmeDeauthInd->peer_macaddr.bytes, pStaDs->staAddr,
1103 		     QDF_MAC_ADDR_SIZE);
1104 	pSirSmeDeauthInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
1105 
1106 	pSirSmeDeauthInd->staId = pStaDs->staIndex;
1107 	if (eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON ==
1108 		pStaDs->mlmStaContext.disassocReason)
1109 		pSirSmeDeauthInd->rssi = pStaDs->del_sta_ctx_rssi;
1110 
1111 	mmhMsg.type = eWNI_SME_DEAUTH_IND;
1112 	mmhMsg.bodyptr = pSirSmeDeauthInd;
1113 	mmhMsg.bodyval = 0;
1114 
1115 	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
1116 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
1117 	lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, psessionEntry,
1118 			      0, pStaDs->mlmStaContext.cleanupTrigger);
1119 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1120 
1121 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1122 	return;
1123 } /*** end lim_send_sme_deauth_ind() ***/
1124 
1125 #ifdef FEATURE_WLAN_TDLS
1126 /**
1127  * lim_send_sme_tdls_del_sta_ind()
1128  *
1129  ***FUNCTION:
1130  * This function is called to send the TDLS STA context deletion to SME.
1131  *
1132  ***LOGIC:
1133  *
1134  ***ASSUMPTIONS:
1135  *
1136  ***NOTE:
1137  * NA
1138  *
1139  * @param  pMac   - Pointer to global MAC structure
1140  * @param  pStaDs - Pointer to internal STA Datastructure
1141  * @param  psessionEntry - Pointer to the session entry
1142  * @param  reasonCode - Reason for TDLS sta deletion
1143  * @return None
1144  */
1145 void
1146 lim_send_sme_tdls_del_sta_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
1147 			      tpPESession psessionEntry, uint16_t reasonCode)
1148 {
1149 	tSirMsgQ mmhMsg;
1150 	tSirTdlsDelStaInd *pSirTdlsDelStaInd;
1151 
1152 	pSirTdlsDelStaInd = qdf_mem_malloc(sizeof(tSirTdlsDelStaInd));
1153 	if (NULL == pSirTdlsDelStaInd) {
1154 		lim_log(pMac, LOGP,
1155 			FL
1156 				("AllocateMemory failed for eWNI_SME_TDLS_DEL_STA_IND "));
1157 		return;
1158 	}
1159 	/* messageType */
1160 	pSirTdlsDelStaInd->messageType = eWNI_SME_TDLS_DEL_STA_IND;
1161 	pSirTdlsDelStaInd->length = sizeof(tSirTdlsDelStaInd);
1162 
1163 	/* sessionId */
1164 	pSirTdlsDelStaInd->sessionId = psessionEntry->smeSessionId;
1165 
1166 	/* peerMacAddr */
1167 	qdf_mem_copy(pSirTdlsDelStaInd->peermac.bytes, pStaDs->staAddr,
1168 		     QDF_MAC_ADDR_SIZE);
1169 
1170 	/* staId */
1171 	lim_copy_u16((uint8_t *) (&pSirTdlsDelStaInd->staId),
1172 		     (uint16_t) pStaDs->staIndex);
1173 
1174 	/* reasonCode */
1175 	lim_copy_u16((uint8_t *) (&pSirTdlsDelStaInd->reasonCode), reasonCode);
1176 
1177 	mmhMsg.type = eWNI_SME_TDLS_DEL_STA_IND;
1178 	mmhMsg.bodyptr = pSirTdlsDelStaInd;
1179 	mmhMsg.bodyval = 0;
1180 
1181 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1182 	return;
1183 } /*** end lim_send_sme_tdls_del_sta_ind() ***/
1184 
1185 /**
1186  * lim_send_sme_tdls_delete_all_peer_ind()
1187  *
1188  ***FUNCTION:
1189  * This function is called to send the eWNI_SME_TDLS_DEL_ALL_PEER_IND
1190  * message to SME.
1191  *
1192  ***LOGIC:
1193  *
1194  ***ASSUMPTIONS:
1195  *
1196  ***NOTE:
1197  * NA
1198  *
1199  * @param  pMac   - Pointer to global MAC structure
1200  * @param  psessionEntry - Pointer to the session entry
1201  * @return None
1202  */
1203 void
1204 lim_send_sme_tdls_delete_all_peer_ind(tpAniSirGlobal pMac, tpPESession psessionEntry)
1205 {
1206 	tSirMsgQ mmhMsg;
1207 	tSirTdlsDelAllPeerInd *pSirTdlsDelAllPeerInd;
1208 
1209 	pSirTdlsDelAllPeerInd = qdf_mem_malloc(sizeof(tSirTdlsDelAllPeerInd));
1210 	if (NULL == pSirTdlsDelAllPeerInd) {
1211 		lim_log(pMac, LOGP,
1212 			FL
1213 				("AllocateMemory failed for eWNI_SME_TDLS_DEL_ALL_PEER_IND"));
1214 		return;
1215 	}
1216 	/* messageType */
1217 	pSirTdlsDelAllPeerInd->messageType = eWNI_SME_TDLS_DEL_ALL_PEER_IND;
1218 	pSirTdlsDelAllPeerInd->length = sizeof(tSirTdlsDelAllPeerInd);
1219 
1220 	/* sessionId */
1221 	pSirTdlsDelAllPeerInd->sessionId = psessionEntry->smeSessionId;
1222 
1223 	mmhMsg.type = eWNI_SME_TDLS_DEL_ALL_PEER_IND;
1224 	mmhMsg.bodyptr = pSirTdlsDelAllPeerInd;
1225 	mmhMsg.bodyval = 0;
1226 
1227 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1228 	return;
1229 } /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/
1230 
1231 /**
1232  * lim_send_sme_mgmt_tx_completion()
1233  *
1234  ***FUNCTION:
1235  * This function is called to send the eWNI_SME_MGMT_FRM_TX_COMPLETION_IND
1236  * message to SME.
1237  *
1238  ***LOGIC:
1239  *
1240  ***ASSUMPTIONS:
1241  *
1242  ***NOTE:
1243  * NA
1244  *
1245  * @param  pMac   - Pointer to global MAC structure
1246  * @param  psessionEntry - Pointer to the session entry
1247  * @param  txCompleteStatus - TX Complete Status of Mgmt Frames
1248  * @return None
1249  */
1250 void
1251 lim_send_sme_mgmt_tx_completion(tpAniSirGlobal pMac,
1252 				tpPESession psessionEntry, uint32_t txCompleteStatus)
1253 {
1254 	tSirMsgQ mmhMsg;
1255 	tSirMgmtTxCompletionInd *pSirMgmtTxCompletionInd;
1256 
1257 	pSirMgmtTxCompletionInd =
1258 		qdf_mem_malloc(sizeof(tSirMgmtTxCompletionInd));
1259 	if (NULL == pSirMgmtTxCompletionInd) {
1260 		lim_log(pMac, LOGP,
1261 			FL
1262 				("AllocateMemory failed for eWNI_SME_MGMT_FRM_TX_COMPLETION_IND"));
1263 		return;
1264 	}
1265 	/* messageType */
1266 	pSirMgmtTxCompletionInd->messageType =
1267 		eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
1268 	pSirMgmtTxCompletionInd->length = sizeof(tSirMgmtTxCompletionInd);
1269 
1270 	/* sessionId */
1271 	pSirMgmtTxCompletionInd->sessionId = psessionEntry->smeSessionId;
1272 
1273 	pSirMgmtTxCompletionInd->txCompleteStatus = txCompleteStatus;
1274 
1275 	mmhMsg.type = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
1276 	mmhMsg.bodyptr = pSirMgmtTxCompletionInd;
1277 	mmhMsg.bodyval = 0;
1278 
1279 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1280 	return;
1281 } /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/
1282 
1283 void lim_send_sme_tdls_event_notify(tpAniSirGlobal pMac, uint16_t msgType,
1284 				    void *events)
1285 {
1286 	tSirMsgQ mmhMsg;
1287 
1288 	switch (msgType) {
1289 	case SIR_HAL_TDLS_SHOULD_DISCOVER:
1290 		mmhMsg.type = eWNI_SME_TDLS_SHOULD_DISCOVER;
1291 		break;
1292 	case SIR_HAL_TDLS_SHOULD_TEARDOWN:
1293 		mmhMsg.type = eWNI_SME_TDLS_SHOULD_TEARDOWN;
1294 		break;
1295 	case SIR_HAL_TDLS_PEER_DISCONNECTED:
1296 		mmhMsg.type = eWNI_SME_TDLS_PEER_DISCONNECTED;
1297 		break;
1298 	case SIR_HAL_TDLS_CONNECTION_TRACKER_NOTIFICATION:
1299 		mmhMsg.type = eWNI_SME_TDLS_CONNECTION_TRACKER_NOTIFICATION;
1300 		break;
1301 	}
1302 
1303 	mmhMsg.bodyptr = events;
1304 	mmhMsg.bodyval = 0;
1305 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1306 	return;
1307 }
1308 #endif /* FEATURE_WLAN_TDLS */
1309 
1310 /**
1311  * lim_send_sme_deauth_ntf()
1312  *
1313  ***FUNCTION:
1314  * This function is called by limProcessSmeMessages() to send
1315  * eWNI_SME_DISASSOC_RSP/IND message to host
1316  *
1317  ***PARAMS:
1318  *
1319  ***LOGIC:
1320  *
1321  ***ASSUMPTIONS:
1322  * NA
1323  *
1324  ***NOTE:
1325  * This function is used for sending eWNI_SME_DEAUTH_CNF or
1326  * eWNI_SME_DEAUTH_IND to host depending on deauthentication trigger.
1327  *
1328  * @param peerMacAddr       Indicates the peer MAC addr to which
1329  *                          deauthentication was initiated
1330  * @param reasonCode        Indicates the reason for Deauthetication
1331  * @param deauthTrigger     Indicates the trigger for Deauthetication
1332  * @param aid               Indicates the STAID. This parameter is present
1333  *                          only on AP.
1334  *
1335  * @return None
1336  */
1337 void
1338 lim_send_sme_deauth_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
1339 			tSirResultCodes reasonCode, uint16_t deauthTrigger,
1340 			uint16_t aid, uint8_t smesessionId,
1341 			uint16_t smetransactionId)
1342 {
1343 	uint8_t *pBuf;
1344 	tSirSmeDeauthRsp *pSirSmeDeauthRsp;
1345 	tSirSmeDeauthInd *pSirSmeDeauthInd;
1346 	tpPESession psessionEntry;
1347 	uint8_t sessionId;
1348 	uint32_t *pMsg;
1349 
1350 	psessionEntry = pe_find_session_by_bssid(pMac, peerMacAddr, &sessionId);
1351 	switch (deauthTrigger) {
1352 	case eLIM_PEER_ENTITY_DEAUTH:
1353 		return;
1354 
1355 	case eLIM_HOST_DEAUTH:
1356 		/**
1357 		 * Deauthentication response to host triggered
1358 		 * deauthentication.
1359 		 */
1360 		pSirSmeDeauthRsp = qdf_mem_malloc(sizeof(tSirSmeDeauthRsp));
1361 		if (NULL == pSirSmeDeauthRsp) {
1362 			/* Log error */
1363 			lim_log(pMac, LOGP,
1364 				FL
1365 					("call to AllocateMemory failed for eWNI_SME_DEAUTH_RSP"));
1366 
1367 			return;
1368 		}
1369 		lim_log(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with "
1370 				       "retCode: %d for" MAC_ADDRESS_STR),
1371 			reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
1372 		pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP;
1373 		pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp);
1374 		pSirSmeDeauthRsp->statusCode = reasonCode;
1375 		pSirSmeDeauthRsp->sessionId = smesessionId;
1376 		pSirSmeDeauthRsp->transactionId = smetransactionId;
1377 
1378 		pBuf = (uint8_t *) pSirSmeDeauthRsp->peer_macaddr.bytes;
1379 		qdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
1380 
1381 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
1382 		lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
1383 				      psessionEntry, 0, (uint16_t) reasonCode);
1384 #endif
1385 		pMsg = (uint32_t *) pSirSmeDeauthRsp;
1386 
1387 		break;
1388 
1389 	default:
1390 		/**
1391 		 * Deauthentication indication due to Deauthentication
1392 		 * frame reception from peer entity or due to
1393 		 * loss of link with peer entity.
1394 		 */
1395 		pSirSmeDeauthInd = qdf_mem_malloc(sizeof(tSirSmeDeauthInd));
1396 		if (NULL == pSirSmeDeauthInd) {
1397 			/* Log error */
1398 			lim_log(pMac, LOGP,
1399 				FL
1400 					("call to AllocateMemory failed for eWNI_SME_DEAUTH_Ind"));
1401 
1402 			return;
1403 		}
1404 		lim_log(pMac, LOG1, FL("send eWNI_SME_DEAUTH_IND with "
1405 				       "retCode: %d for " MAC_ADDRESS_STR),
1406 			reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
1407 		pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
1408 		pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
1409 		pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
1410 
1411 		/* sessionId */
1412 		pBuf = (uint8_t *) &pSirSmeDeauthInd->sessionId;
1413 		*pBuf++ = smesessionId;
1414 
1415 		/* transaction ID */
1416 		lim_copy_u16(pBuf, smetransactionId);
1417 		pBuf += sizeof(uint16_t);
1418 
1419 		/* status code */
1420 		lim_copy_u32(pBuf, reasonCode);
1421 		pBuf += sizeof(tSirResultCodes);
1422 
1423 		/* bssId */
1424 		qdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
1425 		pBuf += sizeof(tSirMacAddr);
1426 
1427 		/* peerMacAddr */
1428 		qdf_mem_copy(pSirSmeDeauthInd->peer_macaddr.bytes, peerMacAddr,
1429 			     QDF_MAC_ADDR_SIZE);
1430 
1431 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
1432 		lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT,
1433 				      psessionEntry, 0, (uint16_t) reasonCode);
1434 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1435 		pMsg = (uint32_t *) pSirSmeDeauthInd;
1436 
1437 		break;
1438 	}
1439 
1440 	/*Delete the PE session  created */
1441 	if (psessionEntry != NULL) {
1442 		pe_delete_session(pMac, psessionEntry);
1443 	}
1444 
1445 	lim_send_sme_disassoc_deauth_ntf(pMac, QDF_STATUS_SUCCESS,
1446 					 (uint32_t *) pMsg);
1447 
1448 } /*** end lim_send_sme_deauth_ntf() ***/
1449 
1450 /**
1451  * lim_send_sme_wm_status_change_ntf() - Send Notification
1452  * @mac_ctx:             Global MAC Context
1453  * @status_change_code:  Indicates the change in the wireless medium.
1454  * @status_change_info:  Indicates the information associated with
1455  *                       change in the wireless medium.
1456  * @info_len:            Indicates the length of status change information
1457  *                       being sent.
1458  * @session_id           SessionID
1459  *
1460  * This function is called by limProcessSmeMessages() to send
1461  * eWNI_SME_WM_STATUS_CHANGE_NTF message to host.
1462  *
1463  * Return: None
1464  */
1465 void
1466 lim_send_sme_wm_status_change_ntf(tpAniSirGlobal mac_ctx,
1467 	tSirSmeStatusChangeCode status_change_code,
1468 	uint32_t *status_change_info, uint16_t info_len, uint8_t session_id)
1469 {
1470 	tSirMsgQ msg;
1471 	tSirSmeWmStatusChangeNtf *wm_status_change_ntf;
1472 
1473 	wm_status_change_ntf = qdf_mem_malloc(sizeof(tSirSmeWmStatusChangeNtf));
1474 	if (NULL == wm_status_change_ntf) {
1475 		lim_log(mac_ctx, LOGE,
1476 			FL("Mem Alloc failed - eWNI_SME_WM_STATUS_CHANGE_NTF"));
1477 		return;
1478 	}
1479 
1480 	msg.type = eWNI_SME_WM_STATUS_CHANGE_NTF;
1481 	msg.bodyval = 0;
1482 	msg.bodyptr = wm_status_change_ntf;
1483 
1484 	switch (status_change_code) {
1485 	case eSIR_SME_RADAR_DETECTED:
1486 		break;
1487 	default:
1488 		wm_status_change_ntf->messageType =
1489 			eWNI_SME_WM_STATUS_CHANGE_NTF;
1490 		wm_status_change_ntf->statusChangeCode = status_change_code;
1491 		wm_status_change_ntf->length = sizeof(tSirSmeWmStatusChangeNtf);
1492 		wm_status_change_ntf->sessionId = session_id;
1493 		if (sizeof(wm_status_change_ntf->statusChangeInfo) >=
1494 			info_len) {
1495 			qdf_mem_copy(
1496 			    (uint8_t *) &wm_status_change_ntf->statusChangeInfo,
1497 			    (uint8_t *) status_change_info, info_len);
1498 		}
1499 		lim_log(mac_ctx, LOGE,
1500 			FL("**---** StatusChg: code 0x%x, length %d **---**"),
1501 			status_change_code, info_len);
1502 		break;
1503 	}
1504 
1505 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, session_id, msg.type));
1506 	if (eSIR_SUCCESS != lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT)) {
1507 		qdf_mem_free(wm_status_change_ntf);
1508 		lim_log(mac_ctx, LOGP,
1509 			FL("lim_sys_process_mmh_msg_api failed"));
1510 	}
1511 
1512 } /*** end lim_send_sme_wm_status_change_ntf() ***/
1513 
1514 /**
1515  * lim_send_sme_set_context_rsp()
1516  *
1517  ***FUNCTION:
1518  * This function is called by limProcessSmeMessages() to send
1519  * eWNI_SME_SETCONTEXT_RSP message to host
1520  *
1521  ***PARAMS:
1522  *
1523  ***LOGIC:
1524  *
1525  ***ASSUMPTIONS:
1526  * NA
1527  *
1528  ***NOTE:
1529  *
1530  * @param pMac         Pointer to Global MAC structure
1531  * @param peerMacAddr  Indicates the peer MAC addr to which
1532  *                     setContext was performed
1533  * @param aid          Indicates the aid corresponding to the peer MAC
1534  *                     address
1535  * @param resultCode   Indicates the result of previously issued
1536  *                     eWNI_SME_SETCONTEXT_RSP message
1537  *
1538  * @return None
1539  */
1540 void
1541 lim_send_sme_set_context_rsp(tpAniSirGlobal pMac,
1542 			     struct qdf_mac_addr peer_macaddr, uint16_t aid,
1543 			     tSirResultCodes resultCode,
1544 			     tpPESession psessionEntry, uint8_t smesessionId,
1545 			     uint16_t smetransactionId)
1546 {
1547 	tSirMsgQ mmhMsg;
1548 	tSirSmeSetContextRsp *pSirSmeSetContextRsp;
1549 
1550 	pSirSmeSetContextRsp = qdf_mem_malloc(sizeof(tSirSmeSetContextRsp));
1551 	if (NULL == pSirSmeSetContextRsp) {
1552 		/* Log error */
1553 		lim_log(pMac, LOGP,
1554 			FL
1555 				("call to AllocateMemory failed for SmeSetContextRsp"));
1556 
1557 		return;
1558 	}
1559 
1560 	pSirSmeSetContextRsp->messageType = eWNI_SME_SETCONTEXT_RSP;
1561 	pSirSmeSetContextRsp->length = sizeof(tSirSmeSetContextRsp);
1562 	pSirSmeSetContextRsp->statusCode = resultCode;
1563 
1564 	qdf_copy_macaddr(&pSirSmeSetContextRsp->peer_macaddr, &peer_macaddr);
1565 
1566 	/* Update SME session and transaction Id */
1567 	pSirSmeSetContextRsp->sessionId = smesessionId;
1568 	pSirSmeSetContextRsp->transactionId = smetransactionId;
1569 
1570 	mmhMsg.type = eWNI_SME_SETCONTEXT_RSP;
1571 	mmhMsg.bodyptr = pSirSmeSetContextRsp;
1572 	mmhMsg.bodyval = 0;
1573 	if (NULL == psessionEntry) {
1574 		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
1575 				 NO_SESSION, mmhMsg.type));
1576 	} else {
1577 		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
1578 				 psessionEntry->peSessionId, mmhMsg.type));
1579 	}
1580 
1581 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
1582 	lim_diag_event_report(pMac, WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
1583 			      psessionEntry, (uint16_t) resultCode, 0);
1584 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1585 
1586 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1587 } /*** end lim_send_sme_set_context_rsp() ***/
1588 
1589 /**
1590  * lim_send_sme_neighbor_bss_ind()
1591  *
1592  ***FUNCTION:
1593  * This function is called by lim_lookup_nadd_hash_entry() to send
1594  * eWNI_SME_NEIGHBOR_BSS_IND message to host
1595  *
1596  ***PARAMS:
1597  *
1598  ***LOGIC:
1599  *
1600  ***ASSUMPTIONS:
1601  * NA
1602  *
1603  ***NOTE:
1604  * This function is used for sending eWNI_SME_NEIGHBOR_BSS_IND to
1605  * host upon detecting new BSS during background scanning if CFG
1606  * option is enabled for sending such indication
1607  *
1608  * @param  pMac - Pointer to Global MAC structure
1609  * @return None
1610  */
1611 
1612 void
1613 lim_send_sme_neighbor_bss_ind(tpAniSirGlobal pMac, tLimScanResultNode *pBssDescr)
1614 {
1615 	tSirMsgQ msgQ;
1616 	uint32_t val;
1617 	tSirSmeNeighborBssInd *pNewBssInd;
1618 
1619 	if ((pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_WT_SCAN_STATE) ||
1620 	    ((pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE) &&
1621 	     pMac->lim.gLimRspReqd)) {
1622 		/* LIM is not in background scan state OR */
1623 		/* current scan is initiated by HDD. */
1624 		/* No need to send new BSS indication to HDD */
1625 		return;
1626 	}
1627 
1628 	if (wlan_cfg_get_int(pMac, WNI_CFG_NEW_BSS_FOUND_IND, &val) !=
1629 	    eSIR_SUCCESS) {
1630 		lim_log(pMac, LOGP,
1631 			FL("could not get NEIGHBOR_BSS_IND from CFG"));
1632 
1633 		return;
1634 	}
1635 
1636 	if (val == 0)
1637 		return;
1638 
1639 	/**
1640 	 * Need to indicate new BSSs found during
1641 	 * background scanning to host.
1642 	 * Allocate buffer for sending indication.
1643 	 * Length of buffer is length of BSS description
1644 	 * and length of header itself
1645 	 */
1646 	val = pBssDescr->bssDescription.length + sizeof(uint16_t) +
1647 		sizeof(uint32_t) + sizeof(uint8_t);
1648 	pNewBssInd = qdf_mem_malloc(val);
1649 	if (NULL == pNewBssInd) {
1650 		/* Log error */
1651 		lim_log(pMac, LOGP,
1652 			FL
1653 				("call to AllocateMemory failed for eWNI_SME_NEIGHBOR_BSS_IND"));
1654 
1655 		return;
1656 	}
1657 
1658 	pNewBssInd->messageType = eWNI_SME_NEIGHBOR_BSS_IND;
1659 	pNewBssInd->length = (uint16_t) val;
1660 	pNewBssInd->sessionId = 0;
1661 
1662 	qdf_mem_copy((uint8_t *) pNewBssInd->bssDescription,
1663 		     (uint8_t *) &pBssDescr->bssDescription,
1664 		     pBssDescr->bssDescription.length + sizeof(uint16_t));
1665 
1666 	msgQ.type = eWNI_SME_NEIGHBOR_BSS_IND;
1667 	msgQ.bodyptr = pNewBssInd;
1668 	msgQ.bodyval = 0;
1669 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, msgQ.type));
1670 	lim_sys_process_mmh_msg_api(pMac, &msgQ, ePROT);
1671 } /*** end lim_send_sme_neighbor_bss_ind() ***/
1672 
1673 /** -----------------------------------------------------------------
1674    \brief lim_send_sme_addts_rsp() - sends SME ADDTS RSP
1675  \      This function sends a eWNI_SME_ADDTS_RSP to SME.
1676  \      SME only looks at rc and tspec field.
1677    \param pMac - global mac structure
1678    \param rspReqd - is SmeAddTsRsp required
1679    \param status - status code of SME_ADD_TS_RSP
1680    \return tspec
1681    \sa
1682    ----------------------------------------------------------------- */
1683 void
1684 lim_send_sme_addts_rsp(tpAniSirGlobal pMac, uint8_t rspReqd, uint32_t status,
1685 		       tpPESession psessionEntry, tSirMacTspecIE tspec,
1686 		       uint8_t smesessionId, uint16_t smetransactionId)
1687 {
1688 	tpSirAddtsRsp rsp;
1689 	tSirMsgQ mmhMsg;
1690 
1691 	if (!rspReqd)
1692 		return;
1693 
1694 	rsp = qdf_mem_malloc(sizeof(tSirAddtsRsp));
1695 	if (NULL == rsp) {
1696 		lim_log(pMac, LOGP, FL("AllocateMemory failed for ADDTS_RSP"));
1697 		return;
1698 	}
1699 
1700 	qdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
1701 	rsp->messageType = eWNI_SME_ADDTS_RSP;
1702 	rsp->rc = status;
1703 	rsp->rsp.status = (enum eSirMacStatusCodes)status;
1704 	rsp->rsp.tspec = tspec;
1705 	/* Update SME session Id and transcation Id */
1706 	rsp->sessionId = smesessionId;
1707 	rsp->transactionId = smetransactionId;
1708 
1709 	mmhMsg.type = eWNI_SME_ADDTS_RSP;
1710 	mmhMsg.bodyptr = rsp;
1711 	mmhMsg.bodyval = 0;
1712 	if (NULL == psessionEntry) {
1713 		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
1714 				 NO_SESSION, mmhMsg.type));
1715 	} else {
1716 		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
1717 				 psessionEntry->peSessionId, mmhMsg.type));
1718 	}
1719 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
1720 	lim_diag_event_report(pMac, WLAN_PE_DIAG_ADDTS_RSP_EVENT, psessionEntry, 0,
1721 			      0);
1722 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1723 
1724 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1725 	return;
1726 }
1727 
1728 void
1729 lim_send_sme_delts_rsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, uint32_t status,
1730 		       tpPESession psessionEntry, uint8_t smesessionId,
1731 		       uint16_t smetransactionId)
1732 {
1733 	tpSirDeltsRsp rsp;
1734 	tSirMsgQ mmhMsg;
1735 
1736 	lim_log(pMac, LOGW, "SendSmeDeltsRsp (aid %d, tsid %d, up %d) status %d",
1737 		delts->aid,
1738 		delts->req.tsinfo.traffic.tsid,
1739 		delts->req.tsinfo.traffic.userPrio, status);
1740 	if (!delts->rspReqd)
1741 		return;
1742 
1743 	rsp = qdf_mem_malloc(sizeof(tSirDeltsRsp));
1744 	if (NULL == rsp) {
1745 		/* Log error */
1746 		lim_log(pMac, LOGP, FL("AllocateMemory failed for DELTS_RSP"));
1747 		return;
1748 	}
1749 	qdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
1750 
1751 	if (psessionEntry != NULL) {
1752 
1753 		rsp->aid = delts->aid;
1754 		qdf_copy_macaddr(&rsp->macaddr, &delts->macaddr);
1755 		qdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) &delts->req,
1756 			     sizeof(tSirDeltsReqInfo));
1757 	}
1758 
1759 	rsp->messageType = eWNI_SME_DELTS_RSP;
1760 	rsp->rc = status;
1761 
1762 	/* Update SME session Id and transcation Id */
1763 	rsp->sessionId = smesessionId;
1764 	rsp->transactionId = smetransactionId;
1765 
1766 	mmhMsg.type = eWNI_SME_DELTS_RSP;
1767 	mmhMsg.bodyptr = rsp;
1768 	mmhMsg.bodyval = 0;
1769 	if (NULL == psessionEntry) {
1770 		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
1771 				 NO_SESSION, mmhMsg.type));
1772 	} else {
1773 		MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
1774 				 psessionEntry->peSessionId, mmhMsg.type));
1775 	}
1776 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
1777 	lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_RSP_EVENT, psessionEntry,
1778 			      (uint16_t) status, 0);
1779 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1780 
1781 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1782 }
1783 
1784 void
1785 lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, uint16_t aid,
1786 		       tpPESession psessionEntry)
1787 {
1788 	tpSirDeltsRsp rsp;
1789 	tSirMsgQ mmhMsg;
1790 
1791 	lim_log(pMac, LOGW, "SendSmeDeltsInd (aid %d, tsid %d, up %d)",
1792 		aid, delts->tsinfo.traffic.tsid, delts->tsinfo.traffic.userPrio);
1793 
1794 	rsp = qdf_mem_malloc(sizeof(tSirDeltsRsp));
1795 	if (NULL == rsp) {
1796 		/* Log error */
1797 		lim_log(pMac, LOGP, FL("AllocateMemory failed for DELTS_IND"));
1798 		return;
1799 	}
1800 	qdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
1801 
1802 	rsp->messageType = eWNI_SME_DELTS_IND;
1803 	rsp->rc = eSIR_SUCCESS;
1804 	rsp->aid = aid;
1805 	qdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) delts, sizeof(*delts));
1806 
1807 	/* Update SME  session Id and SME transaction Id */
1808 
1809 	rsp->sessionId = psessionEntry->smeSessionId;
1810 	rsp->transactionId = psessionEntry->transactionId;
1811 
1812 	mmhMsg.type = eWNI_SME_DELTS_IND;
1813 	mmhMsg.bodyptr = rsp;
1814 	mmhMsg.bodyval = 0;
1815 	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
1816 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
1817 	lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_IND_EVENT, psessionEntry, 0,
1818 			      0);
1819 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
1820 
1821 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1822 }
1823 
1824 /**
1825  * lim_send_sme_pe_statistics_rsp()
1826  *
1827  ***FUNCTION:
1828  * This function is called to send 802.11 statistics response to HDD.
1829  * This function posts the result back to HDD. This is a response to
1830  * HDD's request for statistics.
1831  *
1832  ***PARAMS:
1833  *
1834  ***LOGIC:
1835  *
1836  ***ASSUMPTIONS:
1837  * NA
1838  *
1839  ***NOTE:
1840  * NA
1841  *
1842  * @param pMac         Pointer to Global MAC structure
1843  * @param p80211Stats  Statistics sent in response
1844  * @param resultCode   TODO:
1845  *
1846  *
1847  * @return none
1848  */
1849 
1850 void
1851 lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgType, void *stats)
1852 {
1853 	tSirMsgQ mmhMsg;
1854 	uint8_t sessionId;
1855 	tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats;
1856 	tpPESession pPeSessionEntry;
1857 
1858 	/* Get the Session Id based on Sta Id */
1859 	pPeSessionEntry =
1860 		pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId);
1861 
1862 	/* Fill the Session Id */
1863 	if (NULL != pPeSessionEntry) {
1864 		/* Fill the Session Id */
1865 		pPeStats->sessionId = pPeSessionEntry->smeSessionId;
1866 	}
1867 
1868 	pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP;
1869 
1870 	/* msgType should be WMA_GET_STATISTICS_RSP */
1871 	mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP;
1872 
1873 	mmhMsg.bodyptr = stats;
1874 	mmhMsg.bodyval = 0;
1875 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type));
1876 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1877 
1878 	return;
1879 
1880 } /*** end lim_send_sme_pe_statistics_rsp() ***/
1881 
1882 #ifdef FEATURE_WLAN_ESE
1883 /**
1884  * lim_send_sme_pe_ese_tsm_rsp() - send tsm response
1885  * @pMac:   Pointer to global pMac structure
1886  * @pStats: Pointer to TSM Stats
1887  *
1888  * This function is called to send tsm stats response to HDD.
1889  * This function posts the result back to HDD. This is a response to
1890  * HDD's request to get tsm stats.
1891  *
1892  * Return: None
1893  */
1894 void lim_send_sme_pe_ese_tsm_rsp(tpAniSirGlobal pMac,
1895 				 tAniGetTsmStatsRsp *pStats)
1896 {
1897 	tSirMsgQ mmhMsg;
1898 	uint8_t sessionId;
1899 	tAniGetTsmStatsRsp *pPeStats = (tAniGetTsmStatsRsp *) pStats;
1900 	tpPESession pPeSessionEntry = NULL;
1901 
1902 	/* Get the Session Id based on Sta Id */
1903 	pPeSessionEntry =
1904 		pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId);
1905 
1906 	/* Fill the Session Id */
1907 	if (NULL != pPeSessionEntry) {
1908 		/* Fill the Session Id */
1909 		pPeStats->sessionId = pPeSessionEntry->smeSessionId;
1910 	} else {
1911 		PELOGE(lim_log
1912 		       (pMac, LOGE, FL("Session not found for the Sta id(%d)"),
1913 		       pPeStats->staId);)
1914 		return;
1915 	}
1916 
1917 	pPeStats->msgType = eWNI_SME_GET_TSM_STATS_RSP;
1918 	pPeStats->tsmMetrics.RoamingCount
1919 		= pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingCount;
1920 	pPeStats->tsmMetrics.RoamingDly
1921 		= pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly;
1922 
1923 	mmhMsg.type = eWNI_SME_GET_TSM_STATS_RSP;
1924 	mmhMsg.bodyptr = pStats;
1925 	mmhMsg.bodyval = 0;
1926 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type));
1927 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1928 
1929 	return;
1930 } /*** end lim_send_sme_pe_ese_tsm_rsp() ***/
1931 
1932 #endif /* FEATURE_WLAN_ESE */
1933 
1934 void
1935 lim_send_sme_ibss_peer_ind(tpAniSirGlobal pMac,
1936 			   tSirMacAddr peerMacAddr,
1937 			   uint16_t staIndex,
1938 			   uint8_t ucastIdx,
1939 			   uint8_t bcastIdx,
1940 			   uint8_t *beacon,
1941 			   uint16_t beaconLen, uint16_t msgType, uint8_t sessionId)
1942 {
1943 	tSirMsgQ mmhMsg;
1944 	tSmeIbssPeerInd *pNewPeerInd;
1945 
1946 	pNewPeerInd = qdf_mem_malloc(sizeof(tSmeIbssPeerInd) + beaconLen);
1947 	if (NULL == pNewPeerInd) {
1948 		PELOGE(lim_log(pMac, LOGE, FL("Failed to allocate memory"));)
1949 		return;
1950 	}
1951 
1952 	qdf_mem_set((void *)pNewPeerInd, (sizeof(tSmeIbssPeerInd) + beaconLen),
1953 		    0);
1954 
1955 	qdf_mem_copy((uint8_t *) pNewPeerInd->peer_addr.bytes,
1956 		     peerMacAddr, QDF_MAC_ADDR_SIZE);
1957 	pNewPeerInd->staId = staIndex;
1958 	pNewPeerInd->ucastSig = ucastIdx;
1959 	pNewPeerInd->bcastSig = bcastIdx;
1960 	pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen;
1961 	pNewPeerInd->mesgType = msgType;
1962 	pNewPeerInd->sessionId = sessionId;
1963 
1964 	if (beacon != NULL) {
1965 		qdf_mem_copy((void *)((uint8_t *) pNewPeerInd +
1966 				      sizeof(tSmeIbssPeerInd)), (void *)beacon,
1967 			     beaconLen);
1968 	}
1969 
1970 	mmhMsg.type = msgType;
1971 	mmhMsg.bodyptr = pNewPeerInd;
1972 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type));
1973 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
1974 
1975 }
1976 
1977 /**
1978  * lim_handle_csa_offload_msg() - Handle CSA offload message
1979  * @mac_ctx:         pointer to global adapter context
1980  * @msg:             Message pointer.
1981  *
1982  * Return: None
1983  */
1984 void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
1985 {
1986 	tpPESession session_entry;
1987 	tSirMsgQ mmh_msg;
1988 	struct csa_offload_params *csa_params =
1989 				(struct csa_offload_params *) (msg->bodyptr);
1990 	tpSmeCsaOffloadInd csa_offload_ind;
1991 	tpDphHashNode sta_ds = NULL;
1992 	uint8_t session_id;
1993 	uint16_t aid = 0;
1994 	uint16_t chan_space = 0;
1995 	struct ch_params_s ch_params;
1996 
1997 	tLimWiderBWChannelSwitchInfo *chnl_switch_info = NULL;
1998 	tLimChannelSwitchInfo *lim_ch_switch = NULL;
1999 
2000 	lim_log(mac_ctx, LOG1, FL("handle csa offload msg"));
2001 
2002 	if (!csa_params) {
2003 		lim_log(mac_ctx, LOGE, FL("limMsgQ body ptr is NULL"));
2004 		return;
2005 	}
2006 
2007 	session_entry =
2008 		pe_find_session_by_bssid(mac_ctx,
2009 			csa_params->bssId, &session_id);
2010 	if (!session_entry) {
2011 		lim_log(mac_ctx, LOGE,
2012 			FL("Session does not exists for %pM"),
2013 				csa_params->bssId);
2014 		goto err;
2015 	}
2016 
2017 	sta_ds = dph_lookup_hash_entry(mac_ctx, session_entry->bssId, &aid,
2018 		&session_entry->dph.dphHashTable);
2019 
2020 	if (!sta_ds) {
2021 		lim_log(mac_ctx, LOGE,
2022 			FL("sta_ds does not exist"));
2023 		goto err;
2024 	}
2025 
2026 	if (LIM_IS_STA_ROLE(session_entry)) {
2027 		/*
2028 		 * on receiving channel switch announcement from AP, delete all
2029 		 * TDLS peers before leaving BSS and proceed for channel switch
2030 		 */
2031 		lim_delete_tdls_peers(mac_ctx, session_entry);
2032 
2033 		lim_ch_switch = &session_entry->gLimChannelSwitch;
2034 		session_entry->gLimChannelSwitch.switchMode =
2035 			csa_params->switch_mode;
2036 		/* timer already started by firmware, switch immediately */
2037 		session_entry->gLimChannelSwitch.switchCount = 0;
2038 		session_entry->gLimChannelSwitch.primaryChannel =
2039 			csa_params->channel;
2040 		session_entry->gLimChannelSwitch.state =
2041 			eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
2042 		session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ;
2043 		lim_ch_switch->sec_ch_offset =
2044 			session_entry->htSecondaryChannelOffset;
2045 		session_entry->gLimChannelSwitch.ch_center_freq_seg0 = 0;
2046 		session_entry->gLimChannelSwitch.ch_center_freq_seg1 = 0;
2047 		chnl_switch_info =
2048 			&session_entry->gLimWiderBWChannelSwitch;
2049 
2050 		lim_log(mac_ctx, LOG1,
2051 			FL("vht:%d ht:%d flag:%x chan:%d seg1:%d seg2:%d width:%d country:%s class:%d"),
2052 			session_entry->vhtCapability,
2053 			session_entry->htSupportedChannelWidthSet,
2054 			csa_params->ies_present_flag,
2055 			csa_params->channel, csa_params->new_ch_freq_seg1,
2056 			csa_params->new_ch_freq_seg2,
2057 			csa_params->new_ch_width,
2058 			mac_ctx->scan.countryCodeCurrent,
2059 			csa_params->new_op_class);
2060 
2061 		if (session_entry->vhtCapability &&
2062 				session_entry->htSupportedChannelWidthSet) {
2063 			if (csa_params->ies_present_flag & lim_wbw_ie_present) {
2064 				chnl_switch_info->newChanWidth =
2065 					csa_params->new_ch_width;
2066 				chnl_switch_info->newCenterChanFreq0 =
2067 					csa_params->new_ch_freq_seg1;
2068 				chnl_switch_info->newCenterChanFreq1 =
2069 					csa_params->new_ch_freq_seg2;
2070 				session_entry->gLimChannelSwitch.state =
2071 				   eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
2072 				session_entry->gLimChannelSwitch.ch_width =
2073 					csa_params->new_ch_width + 1;
2074 			} else if (csa_params->ies_present_flag
2075 			    & lim_xcsa_ie_present) {
2076 				chan_space =
2077 					cds_reg_dmn_get_chanwidth_from_opclass(
2078 					    mac_ctx->scan.countryCodeCurrent,
2079 					    csa_params->channel,
2080 					    csa_params->new_op_class);
2081 				session_entry->gLimChannelSwitch.state =
2082 				    eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
2083 
2084 				if (chan_space == 80) {
2085 					chnl_switch_info->newChanWidth =
2086 								CH_WIDTH_80MHZ;
2087 				} else if (chan_space == 40) {
2088 					chnl_switch_info->newChanWidth =
2089 								CH_WIDTH_40MHZ;
2090 				} else {
2091 					chnl_switch_info->newChanWidth =
2092 								CH_WIDTH_20MHZ;
2093 					lim_ch_switch->state =
2094 					    eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
2095 				}
2096 
2097 				ch_params.ch_width =
2098 					chnl_switch_info->newChanWidth;
2099 				cds_set_channel_params(csa_params->channel,
2100 						0, &ch_params);
2101 				chnl_switch_info->newCenterChanFreq0 =
2102 					ch_params.center_freq_seg0;
2103 				/*
2104 				* This is not applicable for 20/40/80 MHz.
2105 				* Only used when we support 80+80 MHz operation.
2106 				* In case of 80+80 MHz, this parameter indicates
2107 				* center channel frequency index of 80 MHz
2108 				* channel offrequency segment 1.
2109 				*/
2110 				chnl_switch_info->newCenterChanFreq1 =
2111 					ch_params.center_freq_seg1;
2112 				lim_ch_switch->sec_ch_offset =
2113 					ch_params.sec_ch_offset;
2114 
2115 			}
2116 			session_entry->gLimChannelSwitch.ch_center_freq_seg0 =
2117 				chnl_switch_info->newCenterChanFreq0;
2118 			session_entry->gLimChannelSwitch.ch_center_freq_seg1 =
2119 				chnl_switch_info->newCenterChanFreq1;
2120 			session_entry->gLimChannelSwitch.ch_width =
2121 				chnl_switch_info->newChanWidth;
2122 
2123 		} else if (session_entry->htSupportedChannelWidthSet) {
2124 			if (csa_params->ies_present_flag
2125 			    & lim_xcsa_ie_present) {
2126 				chan_space =
2127 					cds_reg_dmn_get_chanwidth_from_opclass(
2128 					mac_ctx->scan.countryCodeCurrent,
2129 					csa_params->channel,
2130 					csa_params->new_op_class);
2131 				lim_ch_switch->state =
2132 				    eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
2133 				if (chan_space == 40) {
2134 					lim_ch_switch->ch_width =
2135 								CH_WIDTH_40MHZ;
2136 					chnl_switch_info->newChanWidth =
2137 								CH_WIDTH_40MHZ;
2138 					ch_params.ch_width =
2139 						chnl_switch_info->newChanWidth;
2140 					cds_set_channel_params(
2141 							csa_params->channel,
2142 							0, &ch_params);
2143 					lim_ch_switch->ch_center_freq_seg0 =
2144 						ch_params.center_freq_seg0;
2145 					lim_ch_switch->sec_ch_offset =
2146 						ch_params.sec_ch_offset;
2147 				} else {
2148 					lim_ch_switch->ch_width =
2149 								CH_WIDTH_20MHZ;
2150 					chnl_switch_info->newChanWidth =
2151 								CH_WIDTH_40MHZ;
2152 					lim_ch_switch->state =
2153 					    eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
2154 					lim_ch_switch->sec_ch_offset =
2155 						PHY_SINGLE_CHANNEL_CENTERED;
2156 				}
2157 			} else {
2158 				lim_ch_switch->ch_width =
2159 					CH_WIDTH_40MHZ;
2160 				lim_ch_switch->state =
2161 				     eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
2162 				ch_params.ch_width = CH_WIDTH_40MHZ;
2163 				cds_set_channel_params(csa_params->channel,
2164 						0, &ch_params);
2165 				lim_ch_switch->ch_center_freq_seg0 =
2166 					ch_params.center_freq_seg0;
2167 				lim_ch_switch->sec_ch_offset =
2168 					ch_params.sec_ch_offset;
2169 			}
2170 
2171 		}
2172 		lim_log(mac_ctx, LOG1, FL("new ch width = %d space:%d"),
2173 			session_entry->gLimChannelSwitch.ch_width, chan_space);
2174 
2175 		lim_prepare_for11h_channel_switch(mac_ctx, session_entry);
2176 		csa_offload_ind = qdf_mem_malloc(sizeof(tSmeCsaOffloadInd));
2177 		if (NULL == csa_offload_ind) {
2178 			lim_log(mac_ctx, LOGE,
2179 				FL("memalloc fail eWNI_SME_CSA_OFFLOAD_EVENT"));
2180 			goto err;
2181 		}
2182 
2183 		qdf_mem_set(csa_offload_ind, sizeof(tSmeCsaOffloadInd), 0);
2184 		csa_offload_ind->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT;
2185 		csa_offload_ind->mesgLen = sizeof(tSmeCsaOffloadInd);
2186 		qdf_mem_copy(csa_offload_ind->bssid.bytes, session_entry->bssId,
2187 				QDF_MAC_ADDR_SIZE);
2188 		mmh_msg.type = eWNI_SME_CSA_OFFLOAD_EVENT;
2189 		mmh_msg.bodyptr = csa_offload_ind;
2190 		mmh_msg.bodyval = 0;
2191 		lim_log(mac_ctx, LOG1,
2192 			FL("Sending eWNI_SME_CSA_OFFLOAD_EVENT to SME."));
2193 		MTRACE(mac_trace_msg_tx
2194 			(mac_ctx, session_entry->peSessionId, mmh_msg.type));
2195 #ifdef FEATURE_WLAN_DIAG_SUPPORT
2196 		lim_diag_event_report(mac_ctx,
2197 			WLAN_PE_DIAG_SWITCH_CHL_IND_EVENT, session_entry,
2198 			eSIR_SUCCESS, eSIR_SUCCESS);
2199 #endif
2200 		lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
2201 	}
2202 
2203 err:
2204 	qdf_mem_free(csa_params);
2205 }
2206 
2207 /*--------------------------------------------------------------------------
2208    \brief pe_delete_session() - Handle the Delete BSS Response from HAL.
2209 
2210    \param pMac                   - pointer to global adapter context
2211    \param sessionId             - Message pointer.
2212 
2213    \sa
2214    --------------------------------------------------------------------------*/
2215 
2216 void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ MsgQ)
2217 {
2218 	tpPESession psessionEntry;
2219 	tpDeleteBssParams pDelBss = (tpDeleteBssParams) (MsgQ->bodyptr);
2220 
2221 	psessionEntry =
2222 		pe_find_session_by_session_id(pMac, pDelBss->sessionId);
2223 	if (psessionEntry == NULL) {
2224 		lim_log(pMac, LOGE,
2225 			FL("Session Does not exist for given sessionID %d"),
2226 			pDelBss->sessionId);
2227 		qdf_mem_free(MsgQ->bodyptr);
2228 		return;
2229 	}
2230 	if (LIM_IS_IBSS_ROLE(psessionEntry))
2231 		lim_ibss_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
2232 	else if (LIM_IS_UNKNOWN_ROLE(psessionEntry))
2233 		lim_process_sme_del_bss_rsp(pMac, MsgQ->bodyval, psessionEntry);
2234 	else if (LIM_IS_NDI_ROLE(psessionEntry))
2235 		lim_ndi_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
2236 	else
2237 		lim_process_mlm_del_bss_rsp(pMac, MsgQ, psessionEntry);
2238 
2239 }
2240 
2241 /** -----------------------------------------------------------------
2242    \brief lim_send_sme_aggr_qos_rsp() - sends SME FT AGGR QOS RSP
2243  \      This function sends a eWNI_SME_FT_AGGR_QOS_RSP to SME.
2244  \      SME only looks at rc and tspec field.
2245    \param pMac - global mac structure
2246    \param rspReqd - is SmeAddTsRsp required
2247    \param status - status code of eWNI_SME_FT_AGGR_QOS_RSP
2248    \return tspec
2249    \sa
2250    ----------------------------------------------------------------- */
2251 void
2252 lim_send_sme_aggr_qos_rsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp,
2253 			  uint8_t smesessionId)
2254 {
2255 	tSirMsgQ mmhMsg;
2256 
2257 	mmhMsg.type = eWNI_SME_FT_AGGR_QOS_RSP;
2258 	mmhMsg.bodyptr = aggrQosRsp;
2259 	mmhMsg.bodyval = 0;
2260 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
2261 			 smesessionId, mmhMsg.type));
2262 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2263 
2264 	return;
2265 }
2266 
2267 void lim_send_sme_max_assoc_exceeded_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
2268 					 uint8_t smesessionId)
2269 {
2270 	tSirMsgQ mmhMsg;
2271 	tSmeMaxAssocInd *pSmeMaxAssocInd;
2272 
2273 	pSmeMaxAssocInd = qdf_mem_malloc(sizeof(tSmeMaxAssocInd));
2274 	if (NULL == pSmeMaxAssocInd) {
2275 		PELOGE(lim_log(pMac, LOGE, FL("Failed to allocate memory"));)
2276 		return;
2277 	}
2278 	qdf_mem_set((void *)pSmeMaxAssocInd, sizeof(tSmeMaxAssocInd), 0);
2279 	qdf_mem_copy((uint8_t *) pSmeMaxAssocInd->peer_mac.bytes,
2280 		     (uint8_t *) peerMacAddr, QDF_MAC_ADDR_SIZE);
2281 	pSmeMaxAssocInd->mesgType = eWNI_SME_MAX_ASSOC_EXCEEDED;
2282 	pSmeMaxAssocInd->mesgLen = sizeof(tSmeMaxAssocInd);
2283 	pSmeMaxAssocInd->sessionId = smesessionId;
2284 	mmhMsg.type = pSmeMaxAssocInd->mesgType;
2285 	mmhMsg.bodyptr = pSmeMaxAssocInd;
2286 	PELOG1(lim_log(pMac, LOG1, FL("msgType %s peerMacAddr " MAC_ADDRESS_STR
2287 				      " sme session id %d"),
2288 		       "eWNI_SME_MAX_ASSOC_EXCEEDED",
2289 		       MAC_ADDR_ARRAY(peerMacAddr));
2290 	       )
2291 	MTRACE(mac_trace(pMac, TRACE_CODE_TX_SME_MSG,
2292 			 smesessionId, mmhMsg.type));
2293 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2294 
2295 	return;
2296 }
2297 
2298 /** -----------------------------------------------------------------
2299    \brief lim_send_sme_dfs_event_notify() - sends
2300    eWNI_SME_DFS_RADAR_FOUND
2301    After receiving WMI_PHYERR_EVENTID indication frame from FW, this
2302    function sends a eWNI_SME_DFS_RADAR_FOUND to SME to notify
2303    that a RADAR is found on current operating channel and SAP-
2304    has to move to a new channel.
2305    \param pMac - global mac structure
2306    \param msgType - message type received from lower layer
2307    \param event - event data received from lower layer
2308    \return none
2309    \sa
2310    ----------------------------------------------------------------- */
2311 void
2312 lim_send_sme_dfs_event_notify(tpAniSirGlobal pMac, uint16_t msgType, void *event)
2313 {
2314 	tSirMsgQ mmhMsg;
2315 	mmhMsg.type = eWNI_SME_DFS_RADAR_FOUND;
2316 	mmhMsg.bodyptr = event;
2317 	mmhMsg.bodyval = 0;
2318 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2319 	return;
2320 }
2321 
2322 /*--------------------------------------------------------------------------
2323    \brief lim_send_dfs_chan_sw_ie_update()
2324    This timer handler updates the channel switch IE in beacon template
2325 
2326    \param pMac - pointer to global adapter context
2327    \return     - channel to scan from valid session else zero.
2328    \sa
2329    --------------------------------------------------------------------------*/
2330 static void
2331 lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal pMac, tpPESession psessionEntry)
2332 {
2333 
2334 	/* Update the beacon template and send to FW */
2335 	if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != eSIR_SUCCESS) {
2336 		PELOGE(lim_log(pMac, LOGE, FL("Unable to set CSA IE in beacon"));)
2337 		return;
2338 	}
2339 
2340 	/* Send update beacon template message */
2341 	lim_send_beacon_ind(pMac, psessionEntry);
2342 	PELOG1(lim_log(pMac, LOG1,
2343 		       FL(" Updated CSA IE, IE COUNT = %d"),
2344 		       psessionEntry->gLimChannelSwitch.switchCount);
2345 	       )
2346 
2347 	return;
2348 }
2349 
2350 /** -----------------------------------------------------------------
2351    \brief lim_send_sme_ap_channel_switch_resp() - sends
2352    eWNI_SME_CHANNEL_CHANGE_RSP
2353    After receiving WMA_SWITCH_CHANNEL_RSP indication this
2354    function sends a eWNI_SME_CHANNEL_CHANGE_RSP to SME to notify
2355    that the Channel change has been done to the specified target
2356    channel in the Channel change request
2357    \param pMac - global mac structure
2358    \param psessionEntry - session info
2359    \param pChnlParams - Channel switch params
2360    --------------------------------------------------------------------*/
2361 void
2362 lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac,
2363 				    tpPESession psessionEntry,
2364 				    tpSwitchChannelParams pChnlParams)
2365 {
2366 	tSirMsgQ mmhMsg;
2367 	tpSwitchChannelParams pSmeSwithChnlParams;
2368 	uint8_t channelId;
2369 	bool is_ch_dfs = false;
2370 	enum phy_ch_width ch_width;
2371 	uint8_t ch_center_freq_seg1;
2372 
2373 	pSmeSwithChnlParams = (tSwitchChannelParams *)
2374 			      qdf_mem_malloc(sizeof(tSwitchChannelParams));
2375 	if (NULL == pSmeSwithChnlParams) {
2376 		lim_log(pMac, LOGP,
2377 			FL("AllocateMemory failed for pSmeSwithChnlParams\n"));
2378 		return;
2379 	}
2380 
2381 	qdf_mem_set((void *)pSmeSwithChnlParams,
2382 		    sizeof(tSwitchChannelParams), 0);
2383 
2384 	qdf_mem_copy(pSmeSwithChnlParams, pChnlParams,
2385 		     sizeof(tSwitchChannelParams));
2386 
2387 	channelId = pSmeSwithChnlParams->channelNumber;
2388 	ch_width = pSmeSwithChnlParams->ch_width;
2389 	ch_center_freq_seg1 = pSmeSwithChnlParams->ch_center_freq_seg1;
2390 
2391 	/*
2392 	 * Pass the sme sessionID to SME instead
2393 	 * PE session ID.
2394 	 */
2395 	pSmeSwithChnlParams->peSessionId = psessionEntry->smeSessionId;
2396 
2397 	mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP;
2398 	mmhMsg.bodyptr = (void *)pSmeSwithChnlParams;
2399 	mmhMsg.bodyval = 0;
2400 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2401 
2402 	/*
2403 	 * We should start beacon transmission only if the new
2404 	 * channel after channel change is Non-DFS. For a DFS
2405 	 * channel, PE will receive an explicit request from
2406 	 * upper layers to start the beacon transmission .
2407 	 */
2408 
2409 	if (ch_width == CH_WIDTH_160MHZ) {
2410 		is_ch_dfs = true;
2411 	} else if (ch_width == CH_WIDTH_80P80MHZ) {
2412 		if (cds_get_channel_state(channelId) == CHANNEL_STATE_DFS ||
2413 		    cds_get_channel_state(ch_center_freq_seg1 -
2414 					SIR_80MHZ_START_CENTER_CH_DIFF) ==
2415 							CHANNEL_STATE_DFS)
2416 			is_ch_dfs = true;
2417 	} else {
2418 		if (cds_get_channel_state(channelId) == CHANNEL_STATE_DFS)
2419 			is_ch_dfs = true;
2420 	}
2421 
2422 	if (!is_ch_dfs) {
2423 		if (channelId == psessionEntry->currentOperChannel) {
2424 			lim_apply_configuration(pMac, psessionEntry);
2425 			lim_send_beacon_ind(pMac, psessionEntry);
2426 		} else {
2427 			PELOG1(lim_log(pMac, LOG1,
2428 				       FL
2429 					       ("Failed to Transmit Beacons on channel = %d"
2430 					       "after AP channel change response"),
2431 				       psessionEntry->bcnLen);
2432 			       )
2433 		}
2434 	}
2435 	return;
2436 }
2437 
2438 /** -----------------------------------------------------------------
2439    \brief lim_process_beacon_tx_success_ind() - This function is used
2440    explicitely to handle successful beacon transmission indication
2441    from the FW. This is a generic event generated by the FW afer the
2442    first beacon is sent out after the beacon template update by the
2443    host
2444    \param pMac - global mac structure
2445    \param psessionEntry - session info
2446    \return none
2447    \sa
2448    ----------------------------------------------------------------- */
2449 void
2450 lim_process_beacon_tx_success_ind(tpAniSirGlobal pMac, uint16_t msgType, void *event)
2451 {
2452 	/* Currently, this event is used only for DFS channel switch announcement
2453 	 * IE update in the template. If required to be used for other IE updates
2454 	 * add appropriate code by introducing a state variable
2455 	 */
2456 	tpPESession psessionEntry;
2457 	tSirMsgQ mmhMsg;
2458 	tSirSmeCSAIeTxCompleteRsp *pChanSwTxResponse;
2459 	struct sir_beacon_tx_complete_rsp *beacon_tx_comp_rsp_ptr;
2460 	uint8_t length = sizeof(tSirSmeCSAIeTxCompleteRsp);
2461 	tpSirFirstBeaconTxCompleteInd pBcnTxInd =
2462 		(tSirFirstBeaconTxCompleteInd *) event;
2463 
2464 	psessionEntry = pe_find_session_by_bss_idx(pMac, pBcnTxInd->bssIdx);
2465 	if (psessionEntry == NULL) {
2466 		lim_log(pMac, LOGE,
2467 			FL("Session Does not exist for given sessionID"));
2468 		return;
2469 	}
2470 
2471 	lim_log(pMac, LOG1, FL("role:%d swIe:%d opIe:%d"),
2472 		GET_LIM_SYSTEM_ROLE(psessionEntry),
2473 		psessionEntry->dfsIncludeChanSwIe,
2474 		psessionEntry->gLimOperatingMode.present);
2475 
2476 	if (LIM_IS_AP_ROLE(psessionEntry) &&
2477 	    true == psessionEntry->dfsIncludeChanSwIe) {
2478 		/* Send only 5 beacons with CSA IE Set in when a radar is detected */
2479 		if (psessionEntry->gLimChannelSwitch.switchCount > 0) {
2480 			/*
2481 			 * Send the next beacon with updated CSA IE count
2482 			 */
2483 			lim_send_dfs_chan_sw_ie_update(pMac, psessionEntry);
2484 			/* Decrement the IE count */
2485 			psessionEntry->gLimChannelSwitch.switchCount--;
2486 		} else {
2487 			/* Done with CSA IE update, send response back to SME */
2488 			psessionEntry->gLimChannelSwitch.switchCount = 0;
2489 			if (pMac->sap.SapDfsInfo.disable_dfs_ch_switch == false)
2490 				psessionEntry->gLimChannelSwitch.switchMode = 0;
2491 			psessionEntry->dfsIncludeChanSwIe = false;
2492 			psessionEntry->dfsIncludeChanWrapperIe = false;
2493 
2494 			pChanSwTxResponse = (tSirSmeCSAIeTxCompleteRsp *)
2495 					    qdf_mem_malloc(length);
2496 
2497 			if (NULL == pChanSwTxResponse) {
2498 				lim_log(pMac, LOGP,
2499 					FL
2500 						("AllocateMemory failed for tSirSmeCSAIeTxCompleteRsp"));
2501 				return;
2502 			}
2503 
2504 			qdf_mem_set((void *)pChanSwTxResponse, length, 0);
2505 			pChanSwTxResponse->sessionId =
2506 				psessionEntry->smeSessionId;
2507 			pChanSwTxResponse->chanSwIeTxStatus =
2508 				QDF_STATUS_SUCCESS;
2509 
2510 			mmhMsg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND;
2511 			mmhMsg.bodyptr = pChanSwTxResponse;
2512 			mmhMsg.bodyval = 0;
2513 			lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2514 		}
2515 	}
2516 
2517 	if (LIM_IS_AP_ROLE(psessionEntry) &&
2518 		psessionEntry->gLimOperatingMode.present) {
2519 		/* Done with nss update, send response back to SME */
2520 		psessionEntry->gLimOperatingMode.present = 0;
2521 		beacon_tx_comp_rsp_ptr = (struct sir_beacon_tx_complete_rsp *)
2522 				qdf_mem_malloc(sizeof(*beacon_tx_comp_rsp_ptr));
2523 		if (NULL == beacon_tx_comp_rsp_ptr) {
2524 			lim_log(pMac, LOGP,
2525 				FL
2526 				("AllocateMemory failed for beacon_tx_comp_rsp_ptr"));
2527 			return;
2528 		}
2529 		qdf_mem_set((void *)beacon_tx_comp_rsp_ptr,
2530 					sizeof(*beacon_tx_comp_rsp_ptr), 0);
2531 		beacon_tx_comp_rsp_ptr->session_id =
2532 			psessionEntry->smeSessionId;
2533 		beacon_tx_comp_rsp_ptr->tx_status = QDF_STATUS_SUCCESS;
2534 		mmhMsg.type = eWNI_SME_NSS_UPDATE_RSP;
2535 		mmhMsg.bodyptr = beacon_tx_comp_rsp_ptr;
2536 		mmhMsg.bodyval = 0;
2537 		lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
2538 	}
2539 	return;
2540 }
2541