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