1 /*
2  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  *
22  * lim_send_messages.c: Provides functions to send messages or Indications to HAL.
23  * Author:    Sunit Bhatia
24  * Date:       09/21/2006
25  * History:-
26  * Date        Modified by            Modification Information
27  *
28  * --------------------------------------------------------------------------
29  *
30  */
31 #include "lim_send_messages.h"
32 #include "lim_trace.h"
33 #include "wlan_reg_services_api.h"
34 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
35 #include "host_diag_core_log.h"
36 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
37 #include "lim_utils.h"
38 #include "wma.h"
39 #include "../../core/src/vdev_mgr_ops.h"
40 
41 /* Max debug string size in bytes  */
42 #define LIM_DEBUG_STRING_SIZE    512
43 
44 /**
45  * lim_send_beacon_params() - updates bcn params to WMA
46  *
47  * @mac                 : pointer to Global Mac structure.
48  * @tpUpdateBeaconParams : pointer to the structure, which contains the beacon
49  * parameters which are changed.
50  *
51  * This function is called to send beacon interval, short preamble or other
52  * parameters to WMA, which are changed and indication is received in beacon.
53  *
54  * @return success if message send is ok, else false.
55  */
lim_send_beacon_params(struct mac_context * mac,tpUpdateBeaconParams pUpdatedBcnParams,struct pe_session * pe_session)56 QDF_STATUS lim_send_beacon_params(struct mac_context *mac,
57 				     tpUpdateBeaconParams pUpdatedBcnParams,
58 				     struct pe_session *pe_session)
59 {
60 	tpUpdateBeaconParams pBcnParams = NULL;
61 	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
62 	struct scheduler_msg msgQ = {0};
63 
64 	pBcnParams = qdf_mem_malloc(sizeof(*pBcnParams));
65 	if (!pBcnParams)
66 		return QDF_STATUS_E_NOMEM;
67 	qdf_mem_copy((uint8_t *) pBcnParams, pUpdatedBcnParams,
68 		     sizeof(*pBcnParams));
69 	msgQ.type = WMA_UPDATE_BEACON_IND;
70 	msgQ.reserved = 0;
71 	msgQ.bodyptr = pBcnParams;
72 	msgQ.bodyval = 0;
73 	pe_debug("Sending WMA_UPDATE_BEACON_IND, paramChangeBitmap in hex: %x",
74 	       pUpdatedBcnParams->paramChangeBitmap);
75 	if (!pe_session) {
76 		qdf_mem_free(pBcnParams);
77 		MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type));
78 		return QDF_STATUS_E_FAILURE;
79 	} else {
80 		MTRACE(mac_trace_msg_tx(mac,
81 					pe_session->peSessionId,
82 					msgQ.type));
83 	}
84 	pBcnParams->vdev_id = pe_session->vdev_id;
85 	retCode = wma_post_ctrl_msg(mac, &msgQ);
86 	if (QDF_STATUS_SUCCESS != retCode) {
87 		qdf_mem_free(pBcnParams);
88 		pe_err("Posting WMA_UPDATE_BEACON_IND, reason=%X",
89 			retCode);
90 	}
91 	lim_send_beacon_ind(mac, pe_session, REASON_DEFAULT);
92 	return retCode;
93 }
94 
lim_send_switch_chnl_params(struct mac_context * mac,struct pe_session * session)95 QDF_STATUS lim_send_switch_chnl_params(struct mac_context *mac,
96 				       struct pe_session *session)
97 {
98 	struct vdev_mlme_obj *mlme_obj;
99 	QDF_STATUS status = QDF_STATUS_SUCCESS;
100 	struct vdev_start_response rsp = {0};
101 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
102 
103 	if (!wma)
104 		return QDF_STATUS_E_FAILURE;
105 
106 	if (!session) {
107 		pe_err("session is NULL");
108 		return QDF_STATUS_E_FAILURE;
109 	}
110 	if (!session->vdev) {
111 		pe_err("vdev is NULL");
112 		return QDF_STATUS_E_FAILURE;
113 	}
114 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(session->vdev);
115 	if (!mlme_obj) {
116 		pe_err("vdev component object is NULL");
117 		return QDF_STATUS_E_FAILURE;
118 	}
119 	status = lim_pre_vdev_start(mac, mlme_obj, session);
120 	if (QDF_IS_STATUS_ERROR(status))
121 		goto send_resp;
122 
123 	session->ch_switch_in_progress = true;
124 
125 	/* we need to defer the message until we
126 	 * get the response back from WMA
127 	 */
128 	SET_LIM_PROCESS_DEFD_MESGS(mac, false);
129 
130 	status = wma_pre_chan_switch_setup(session->vdev_id);
131 	if (status != QDF_STATUS_SUCCESS) {
132 		pe_err("failed status = %d", status);
133 		goto send_resp;
134 	}
135 	status = vdev_mgr_start_send(mlme_obj,
136 				mlme_is_chan_switch_in_progress(session->vdev));
137 	if (status != QDF_STATUS_SUCCESS) {
138 		pe_err("failed status = %d", status);
139 		goto send_resp;
140 	}
141 	wma_post_chan_switch_setup(session->vdev_id);
142 
143 	return QDF_STATUS_SUCCESS;
144 send_resp:
145 	rsp.status = status;
146 	rsp.vdev_id = session->vdev_id;
147 
148 	wma_handle_channel_switch_resp(wma, &rsp);
149 
150 	return QDF_STATUS_SUCCESS;
151 }
152 
lim_send_edca_params(struct mac_context * mac,tSirMacEdcaParamRecord * pUpdatedEdcaParams,uint16_t vdev_id,bool mu_edca)153 QDF_STATUS lim_send_edca_params(struct mac_context *mac,
154 				tSirMacEdcaParamRecord *pUpdatedEdcaParams,
155 				uint16_t vdev_id, bool mu_edca)
156 {
157 	tEdcaParams *pEdcaParams = NULL;
158 	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
159 	struct scheduler_msg msgQ = {0};
160 
161 	pEdcaParams = qdf_mem_malloc(sizeof(tEdcaParams));
162 	if (!pEdcaParams)
163 		return QDF_STATUS_E_NOMEM;
164 	pEdcaParams->vdev_id = vdev_id;
165 	pEdcaParams->acbe = pUpdatedEdcaParams[QCA_WLAN_AC_BE];
166 	pEdcaParams->acbk = pUpdatedEdcaParams[QCA_WLAN_AC_BK];
167 	pEdcaParams->acvi = pUpdatedEdcaParams[QCA_WLAN_AC_VI];
168 	pEdcaParams->acvo = pUpdatedEdcaParams[QCA_WLAN_AC_VO];
169 	pEdcaParams->mu_edca_params = mu_edca;
170 	msgQ.type = WMA_UPDATE_EDCA_PROFILE_IND;
171 	msgQ.reserved = 0;
172 	msgQ.bodyptr = pEdcaParams;
173 	msgQ.bodyval = 0;
174 	pe_debug("Sending WMA_UPDATE_EDCA_PROFILE_IND");
175 	MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type));
176 	retCode = wma_post_ctrl_msg(mac, &msgQ);
177 	if (QDF_STATUS_SUCCESS != retCode) {
178 		qdf_mem_free(pEdcaParams);
179 		pe_err("Posting WMA_UPDATE_EDCA_PROFILE_IND failed, reason=%X",
180 			retCode);
181 	}
182 	return retCode;
183 }
184 
lim_set_active_edca_params(struct mac_context * mac_ctx,tSirMacEdcaParamRecord * edca_params,struct pe_session * pe_session)185 void lim_set_active_edca_params(struct mac_context *mac_ctx,
186 				tSirMacEdcaParamRecord *edca_params,
187 				struct pe_session *pe_session)
188 {
189 	uint8_t ac, new_ac, i;
190 	uint8_t ac_admitted;
191 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
192 	host_log_qos_edca_pkt_type *log_ptr = NULL;
193 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
194 	uint8_t *debug_str;
195 	uint32_t len = 0;
196 
197 	/* Initialize gLimEdcaParamsActive[] to be same as localEdcaParams */
198 	pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_BE] = edca_params[QCA_WLAN_AC_BE];
199 	pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_BK] = edca_params[QCA_WLAN_AC_BK];
200 	pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_VI] = edca_params[QCA_WLAN_AC_VI];
201 	pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_VO] = edca_params[QCA_WLAN_AC_VO];
202 
203 	pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_BE].no_ack =
204 					mac_ctx->no_ack_policy_cfg[QCA_WLAN_AC_BE];
205 	pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_BK].no_ack =
206 					mac_ctx->no_ack_policy_cfg[QCA_WLAN_AC_BK];
207 	pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_VI].no_ack =
208 					mac_ctx->no_ack_policy_cfg[QCA_WLAN_AC_VI];
209 	pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_VO].no_ack =
210 					mac_ctx->no_ack_policy_cfg[QCA_WLAN_AC_VO];
211 	/* An AC requires downgrade if the ACM bit is set, and the AC has not
212 	 * yet been admitted in uplink or bi-directions.
213 	 * If an AC requires downgrade, it will downgrade to the next beset AC
214 	 * for which ACM is not enabled.
215 	 *
216 	 * - There's no need to downgrade AC_BE since it IS the lowest AC. Hence
217 	 *   start the for loop with AC_BK.
218 	 * - If ACM bit is set for an AC, initially downgrade it to AC_BE. Then
219 	 *   traverse thru the AC list. If we do find the next best AC which is
220 	 *   better than AC_BE, then use that one. For example, if ACM bits are set
221 	 *   such that: BE_ACM=1, BK_ACM=1, VI_ACM=1, VO_ACM=0
222 	 *   then all AC will be downgraded to AC_BE.
223 	 */
224 
225 	debug_str = qdf_mem_malloc(LIM_DEBUG_STRING_SIZE);
226 	if (!debug_str)
227 		return;
228 
229 	for (ac = QCA_WLAN_AC_BK; ac <= QCA_WLAN_AC_VO; ac++) {
230 		ac_admitted =
231 			((pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &
232 			 (1 << ac)) >> ac);
233 
234 		len += qdf_scnprintf(debug_str + len,
235 				     LIM_DEBUG_STRING_SIZE - len,
236 				     "AC[%d]:acm=%d ac_admitted=%d,", ac,
237 				     edca_params[ac].aci.acm, ac_admitted);
238 		if ((edca_params[ac].aci.acm == 1) && (ac_admitted == 0)) {
239 			/* Loop backwards through AC values until it finds
240 			 * acm == 0 or reaches QCA_WLAN_AC_BE.
241 			 * Note that for block has no executable statements.
242 			 */
243 			for (i = ac - 1;
244 			    (i > QCA_WLAN_AC_BE &&
245 				(edca_params[i].aci.acm != 0));
246 			     i--)
247 				;
248 			new_ac = i;
249 			len += qdf_scnprintf(debug_str + len,
250 					     LIM_DEBUG_STRING_SIZE - len,
251 					     "AC %d ---> AC %d, ", ac, new_ac);
252 			pe_session->gLimEdcaParamsActive[ac] =
253 				edca_params[new_ac];
254 		}
255 	}
256 
257 	pe_debug("adAdmitMask: uplink 0x%x downlink 0x%x, %s",
258 		 pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK],
259 		 pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK], debug_str);
260 	qdf_mem_free(debug_str);
261 /* log: LOG_WLAN_QOS_EDCA_C */
262 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
263 	WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_edca_pkt_type,
264 				 LOG_WLAN_QOS_EDCA_C);
265 	if (log_ptr) {
266 		tSirMacEdcaParamRecord *rec;
267 
268 		rec = &pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_BE];
269 		log_ptr->aci_be = rec->aci.aci;
270 		log_ptr->cw_be = rec->cw.max << 4 | rec->cw.min;
271 		log_ptr->txoplimit_be = rec->txoplimit;
272 
273 		rec = &pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_BK];
274 		log_ptr->aci_bk = rec->aci.aci;
275 		log_ptr->cw_bk = rec->cw.max << 4 | rec->cw.min;
276 		log_ptr->txoplimit_bk = rec->txoplimit;
277 
278 		rec = &pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_VI];
279 		log_ptr->aci_vi = rec->aci.aci;
280 		log_ptr->cw_vi = rec->cw.max << 4 | rec->cw.min;
281 		log_ptr->txoplimit_vi = rec->txoplimit;
282 
283 		rec = &pe_session->gLimEdcaParamsActive[QCA_WLAN_AC_VO];
284 		log_ptr->aci_vo = rec->aci.aci;
285 		log_ptr->cw_vo = rec->cw.max << 4 | rec->cw.min;
286 		log_ptr->txoplimit_vo = rec->txoplimit;
287 	}
288 	WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
289 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
290 
291 	return;
292 }
293 
lim_send_mode_update(struct mac_context * mac,tUpdateVHTOpMode * pTempParam,struct pe_session * pe_session)294 QDF_STATUS lim_send_mode_update(struct mac_context *mac,
295 				   tUpdateVHTOpMode *pTempParam,
296 				   struct pe_session *pe_session)
297 {
298 	tUpdateVHTOpMode *pVhtOpMode = NULL;
299 	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
300 	struct scheduler_msg msgQ = {0};
301 
302 	pVhtOpMode = qdf_mem_malloc(sizeof(tUpdateVHTOpMode));
303 	if (!pVhtOpMode)
304 		return QDF_STATUS_E_NOMEM;
305 	qdf_mem_copy((uint8_t *) pVhtOpMode, pTempParam,
306 		     sizeof(tUpdateVHTOpMode));
307 	msgQ.type = WMA_UPDATE_OP_MODE;
308 	msgQ.reserved = 0;
309 	msgQ.bodyptr = pVhtOpMode;
310 	msgQ.bodyval = 0;
311 	pe_debug("Sending WMA_UPDATE_OP_MODE, op_mode %d",
312 			pVhtOpMode->opMode);
313 	if (!pe_session)
314 		MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type));
315 	else
316 		MTRACE(mac_trace_msg_tx(mac,
317 					pe_session->peSessionId,
318 					msgQ.type));
319 	retCode = wma_post_ctrl_msg(mac, &msgQ);
320 	if (QDF_STATUS_SUCCESS != retCode) {
321 		qdf_mem_free(pVhtOpMode);
322 		pe_err("Posting WMA_UPDATE_OP_MODE failed, reason=%X",
323 			retCode);
324 	}
325 
326 	return retCode;
327 }
328 
lim_send_rx_nss_update(struct mac_context * mac,tUpdateRxNss * pTempParam,struct pe_session * pe_session)329 QDF_STATUS lim_send_rx_nss_update(struct mac_context *mac,
330 				     tUpdateRxNss *pTempParam,
331 				     struct pe_session *pe_session)
332 {
333 	tUpdateRxNss *pRxNss = NULL;
334 	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
335 	struct scheduler_msg msgQ = {0};
336 
337 	pRxNss = qdf_mem_malloc(sizeof(tUpdateRxNss));
338 	if (!pRxNss)
339 		return QDF_STATUS_E_NOMEM;
340 	qdf_mem_copy((uint8_t *) pRxNss, pTempParam, sizeof(tUpdateRxNss));
341 	msgQ.type = WMA_UPDATE_RX_NSS;
342 	msgQ.reserved = 0;
343 	msgQ.bodyptr = pRxNss;
344 	msgQ.bodyval = 0;
345 	pe_debug("Sending WMA_UPDATE_RX_NSS");
346 	if (!pe_session)
347 		MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type));
348 	else
349 		MTRACE(mac_trace_msg_tx(mac,
350 					pe_session->peSessionId,
351 					msgQ.type));
352 	retCode = wma_post_ctrl_msg(mac, &msgQ);
353 	if (QDF_STATUS_SUCCESS != retCode) {
354 		qdf_mem_free(pRxNss);
355 		pe_err("Posting WMA_UPDATE_RX_NSS failed, reason=%X",
356 			retCode);
357 	}
358 
359 	return retCode;
360 }
361 
lim_set_membership(struct mac_context * mac,tUpdateMembership * pTempParam,struct pe_session * pe_session)362 QDF_STATUS lim_set_membership(struct mac_context *mac,
363 				 tUpdateMembership *pTempParam,
364 				 struct pe_session *pe_session)
365 {
366 	tUpdateMembership *pMembership = NULL;
367 	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
368 	struct scheduler_msg msgQ = {0};
369 
370 	pMembership = qdf_mem_malloc(sizeof(tUpdateMembership));
371 	if (!pMembership)
372 		return QDF_STATUS_E_NOMEM;
373 	qdf_mem_copy((uint8_t *) pMembership, pTempParam,
374 		     sizeof(tUpdateMembership));
375 
376 	msgQ.type = WMA_UPDATE_MEMBERSHIP;
377 	msgQ.reserved = 0;
378 	msgQ.bodyptr = pMembership;
379 	msgQ.bodyval = 0;
380 	pe_debug("Sending WMA_UPDATE_MEMBERSHIP");
381 	if (!pe_session)
382 		MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type));
383 	else
384 		MTRACE(mac_trace_msg_tx(mac,
385 					pe_session->peSessionId,
386 					msgQ.type));
387 	retCode = wma_post_ctrl_msg(mac, &msgQ);
388 	if (QDF_STATUS_SUCCESS != retCode) {
389 		qdf_mem_free(pMembership);
390 		pe_err("Posting WMA_UPDATE_MEMBERSHIP failed, reason=%X",
391 			retCode);
392 	}
393 
394 	return retCode;
395 }
396 
lim_set_user_pos(struct mac_context * mac,tUpdateUserPos * pTempParam,struct pe_session * pe_session)397 QDF_STATUS lim_set_user_pos(struct mac_context *mac,
398 			       tUpdateUserPos *pTempParam,
399 			       struct pe_session *pe_session)
400 {
401 	tUpdateUserPos *pUserPos = NULL;
402 	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
403 	struct scheduler_msg msgQ = {0};
404 
405 	pUserPos = qdf_mem_malloc(sizeof(tUpdateUserPos));
406 	if (!pUserPos)
407 		return QDF_STATUS_E_NOMEM;
408 	qdf_mem_copy((uint8_t *) pUserPos, pTempParam, sizeof(tUpdateUserPos));
409 
410 	msgQ.type = WMA_UPDATE_USERPOS;
411 	msgQ.reserved = 0;
412 	msgQ.bodyptr = pUserPos;
413 	msgQ.bodyval = 0;
414 	pe_debug("Sending WMA_UPDATE_USERPOS");
415 	if (!pe_session)
416 		MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type));
417 	else
418 		MTRACE(mac_trace_msg_tx(mac,
419 					pe_session->peSessionId,
420 					msgQ.type));
421 	retCode = wma_post_ctrl_msg(mac, &msgQ);
422 	if (QDF_STATUS_SUCCESS != retCode) {
423 		qdf_mem_free(pUserPos);
424 		pe_err("Posting WMA_UPDATE_USERPOS failed, reason=%X",
425 			retCode);
426 	}
427 
428 	return retCode;
429 }
430 
431 /**
432  * lim_send_exclude_unencrypt_ind() - sends WMA_EXCLUDE_UNENCRYPTED_IND to HAL
433  * @mac:          mac global context
434  * @excludeUnenc:  true: ignore, false: indicate
435  * @pe_session: session context
436  *
437  * LIM sends a message to HAL to indicate whether to ignore or indicate the
438  * unprotected packet error.
439  *
440  * Return: status of operation
441  */
lim_send_exclude_unencrypt_ind(struct mac_context * mac,bool excludeUnenc,struct pe_session * pe_session)442 QDF_STATUS lim_send_exclude_unencrypt_ind(struct mac_context *mac,
443 					     bool excludeUnenc,
444 					     struct pe_session *pe_session)
445 {
446 	QDF_STATUS retCode = QDF_STATUS_SUCCESS;
447 	struct scheduler_msg msgQ = {0};
448 	tSirWlanExcludeUnencryptParam *pExcludeUnencryptParam;
449 
450 	pExcludeUnencryptParam =
451 		qdf_mem_malloc(sizeof(tSirWlanExcludeUnencryptParam));
452 	if (!pExcludeUnencryptParam)
453 		return QDF_STATUS_E_NOMEM;
454 
455 	pExcludeUnencryptParam->excludeUnencrypt = excludeUnenc;
456 	qdf_mem_copy(pExcludeUnencryptParam->bssid.bytes, pe_session->bssId,
457 			QDF_MAC_ADDR_SIZE);
458 
459 	msgQ.type = WMA_EXCLUDE_UNENCRYPTED_IND;
460 	msgQ.reserved = 0;
461 	msgQ.bodyptr = pExcludeUnencryptParam;
462 	msgQ.bodyval = 0;
463 	pe_debug("Sending WMA_EXCLUDE_UNENCRYPTED_IND");
464 	MTRACE(mac_trace_msg_tx(mac, pe_session->peSessionId, msgQ.type));
465 	retCode = wma_post_ctrl_msg(mac, &msgQ);
466 	if (QDF_STATUS_SUCCESS != retCode) {
467 		qdf_mem_free(pExcludeUnencryptParam);
468 		pe_err("Posting WMA_EXCLUDE_UNENCRYPTED_IND failed, reason=%X",
469 			retCode);
470 	}
471 
472 	return retCode;
473 }
474 
475 /**
476  * lim_send_ht40_obss_scanind() - send ht40 obss start scan request
477  * mac: mac context
478  * session  PE session handle
479  *
480  * LIM sends a HT40 start scan message to WMA
481  *
482  * Return: status of operation
483  */
lim_send_ht40_obss_scanind(struct mac_context * mac_ctx,struct pe_session * session)484 QDF_STATUS lim_send_ht40_obss_scanind(struct mac_context *mac_ctx,
485 						struct pe_session *session)
486 {
487 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
488 	struct obss_ht40_scanind *ht40_obss_scanind;
489 	uint32_t channelnum, chan_freq;
490 	struct scheduler_msg msg = {0};
491 	uint8_t channel24gnum, count;
492 	uint8_t reg_cc[REG_ALPHA2_LEN + 1];
493 
494 	ht40_obss_scanind = qdf_mem_malloc(sizeof(struct obss_ht40_scanind));
495 	if (!ht40_obss_scanind)
496 		return QDF_STATUS_E_FAILURE;
497 
498 	wlan_reg_read_current_country(mac_ctx->psoc, reg_cc);
499 	ht40_obss_scanind->cmd = HT40_OBSS_SCAN_PARAM_START;
500 	ht40_obss_scanind->scan_type = eSIR_ACTIVE_SCAN;
501 	ht40_obss_scanind->obss_passive_dwelltime =
502 		session->obss_ht40_scanparam.obss_passive_dwelltime;
503 	ht40_obss_scanind->obss_active_dwelltime =
504 		session->obss_ht40_scanparam.obss_active_dwelltime;
505 	ht40_obss_scanind->obss_width_trigger_interval =
506 		session->obss_ht40_scanparam.obss_width_trigger_interval;
507 	ht40_obss_scanind->obss_passive_total_per_channel =
508 		session->obss_ht40_scanparam.obss_passive_total_per_channel;
509 	ht40_obss_scanind->obss_active_total_per_channel =
510 		session->obss_ht40_scanparam.obss_active_total_per_channel;
511 	ht40_obss_scanind->bsswidth_ch_trans_delay =
512 		session->obss_ht40_scanparam.bsswidth_ch_trans_delay;
513 	ht40_obss_scanind->obss_activity_threshold =
514 		session->obss_ht40_scanparam.obss_activity_threshold;
515 	ht40_obss_scanind->current_operatingclass =
516 		wlan_reg_dmn_get_opclass_from_channel(
517 			reg_cc,
518 			wlan_reg_freq_to_chan(
519 			mac_ctx->pdev, session->curr_op_freq),
520 			session->ch_width);
521 	channelnum = mac_ctx->mlme_cfg->reg.valid_channel_list_num;
522 
523 	/* Extract 24G channel list */
524 	channel24gnum = 0;
525 	for (count = 0; count < channelnum &&
526 		(channel24gnum < CFG_VALID_CHANNEL_LIST_LEN); count++) {
527 		chan_freq =
528 			mac_ctx->mlme_cfg->reg.valid_channel_freq_list[count];
529 		if (wlan_reg_is_24ghz_ch_freq(chan_freq)) {
530 			ht40_obss_scanind->chan_freq_list[channel24gnum] =
531 				chan_freq;
532 			channel24gnum++;
533 		}
534 	}
535 	ht40_obss_scanind->channel_count = channel24gnum;
536 	/* FW API requests BSS IDX */
537 	ht40_obss_scanind->bss_id = session->vdev_id;
538 	ht40_obss_scanind->fortymhz_intolerent = 0;
539 	ht40_obss_scanind->iefield_len = 0;
540 	msg.type = WMA_HT40_OBSS_SCAN_IND;
541 	msg.reserved = 0;
542 	msg.bodyptr = (void *)ht40_obss_scanind;
543 	msg.bodyval = 0;
544 	pe_debug("Obss Scan trigger width: %d, delay factor: %d bssid " QDF_MAC_ADDR_FMT,
545 		 ht40_obss_scanind->obss_width_trigger_interval,
546 		 ht40_obss_scanind->bsswidth_ch_trans_delay,
547 		 QDF_MAC_ADDR_REF(session->bssId));
548 	ret = wma_post_ctrl_msg(mac_ctx, &msg);
549 	if (QDF_STATUS_SUCCESS != ret) {
550 		pe_err("WDA_HT40_OBSS_SCAN_IND msg failed, reason=%X",
551 			ret);
552 		qdf_mem_free(ht40_obss_scanind);
553 	}
554 	return ret;
555 }
556 
557 QDF_STATUS
lim_send_edca_pifs_param(struct mac_context * mac,struct wlan_edca_pifs_param_ie * param,uint8_t vdev_id)558 lim_send_edca_pifs_param(struct mac_context *mac,
559 			 struct wlan_edca_pifs_param_ie *param,
560 			 uint8_t vdev_id)
561 {
562 	struct edca_pifs_vparam *edca_pifs = NULL;
563 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
564 	struct scheduler_msg msgQ = {0};
565 
566 	edca_pifs = qdf_mem_malloc(sizeof(*edca_pifs));
567 	if (!edca_pifs)
568 		return QDF_STATUS_E_NOMEM;
569 
570 	edca_pifs->vdev_id = vdev_id;
571 	qdf_mem_copy(&edca_pifs->param, param,
572 		     sizeof(struct wlan_edca_pifs_param_ie));
573 
574 	msgQ.type = WMA_UPDATE_EDCA_PIFS_PARAM_IND;
575 	msgQ.reserved = 0;
576 	msgQ.bodyptr = edca_pifs;
577 	msgQ.bodyval = 0;
578 	pe_debug("Sending WMA_UPDATE_EDCA_PIFS_PARAM_IND");
579 	MTRACE(mac_trace_msg_tx(mac, NO_SESSION, msgQ.type));
580 	ret = wma_post_ctrl_msg(mac, &msgQ);
581 	if (QDF_IS_STATUS_ERROR(ret)) {
582 		qdf_mem_free(edca_pifs);
583 		pe_err("Posting WMA_UPDATE_EDCA_PIFS_PARAM_IND failed, reason=%X",
584 		       ret);
585 	}
586 	return ret;
587 }
588