blob: 0676686d68e07171f38a1013d43454d09e6b7fe5 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2013-2015 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 * DOC: wma_main.c
30 *
31 * This file contains wma initialization and FW exchange
32 * related functions.
33 */
34
35/* Header files */
36
37#include "wma.h"
38#include "wma_api.h"
39#include "cds_api.h"
40#include "wmi_unified_api.h"
41#include "wlan_qct_sys.h"
42#include "wni_api.h"
43#include "ani_global.h"
44#include "wmi_unified.h"
45#include "wni_cfg.h"
46#include "cfg_api.h"
47#include "ol_txrx_ctrl_api.h"
48#include "wlan_tgt_def_config.h"
49
50#include "cdf_nbuf.h"
51#include "cdf_types.h"
52#include "ol_txrx_api.h"
53#include "cdf_memory.h"
54#include "ol_txrx_types.h"
55#include "ol_txrx_peer_find.h"
56
57#include "wma_types.h"
58#include "lim_api.h"
59#include "lim_session_utils.h"
60
61#include "cds_utils.h"
62
63#if !defined(REMOVE_PKT_LOG)
64#include "pktlog_ac.h"
65#endif /* REMOVE_PKT_LOG */
66
67#include "dbglog_host.h"
68/* FIXME: Inclusion of .c looks odd
69 * but this is how it is in internal codebase
70 */
71#include "wmi_version_whitelist.c"
72#include "csr_api.h"
73#include "ol_fw.h"
74
75#include "dfs.h"
76#include "wma_internal.h"
77
78#include "wma_ocb.h"
79
80#define WMA_LOG_COMPLETION_TIMER 10000 /* 10 seconds */
81#define WMA_SERVICE_READY_EXT_TIMEOUT 2000 /* 2 seconds */
82
83static uint32_t g_fw_wlan_feat_caps;
84
85/**
86 * wma_get_fw_wlan_feat_caps() - get fw feature capablity
87 * @featEnumValue: feature enum value
88 *
89 * Return: true/false
90 */
91uint8_t wma_get_fw_wlan_feat_caps(uint8_t featEnumValue)
92{
93 return (g_fw_wlan_feat_caps & (1 << featEnumValue)) ? true : false;
94}
95
96/**
97 * wma_set_default_tgt_config() - set default tgt config
98 * @wma_handle: wma handle
99 *
100 * Return: none
101 */
102static void wma_set_default_tgt_config(tp_wma_handle wma_handle)
103{
104 struct ol_softc *scn;
105 uint8_t no_of_peers_supported;
106 wmi_resource_config tgt_cfg = {
107 0, /* Filling zero for TLV Tag and Length fields */
108 CFG_TGT_NUM_VDEV,
109 CFG_TGT_NUM_PEERS + CFG_TGT_NUM_VDEV + 2,
110 CFG_TGT_NUM_OFFLOAD_PEERS,
111 CFG_TGT_NUM_OFFLOAD_REORDER_BUFFS,
112 CFG_TGT_NUM_PEER_KEYS,
113 CFG_TGT_NUM_TIDS,
114 CFG_TGT_AST_SKID_LIMIT,
115 CFG_TGT_DEFAULT_TX_CHAIN_MASK,
116 CFG_TGT_DEFAULT_RX_CHAIN_MASK,
117 {CFG_TGT_RX_TIMEOUT_LO_PRI, CFG_TGT_RX_TIMEOUT_LO_PRI,
118 CFG_TGT_RX_TIMEOUT_LO_PRI, CFG_TGT_RX_TIMEOUT_HI_PRI},
119 CFG_TGT_RX_DECAP_MODE,
120 CFG_TGT_DEFAULT_SCAN_MAX_REQS,
121 CFG_TGT_DEFAULT_BMISS_OFFLOAD_MAX_VDEV,
122 CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_VDEV,
123 CFG_TGT_DEFAULT_ROAM_OFFLOAD_MAX_PROFILES,
124 CFG_TGT_DEFAULT_NUM_MCAST_GROUPS,
125 CFG_TGT_DEFAULT_NUM_MCAST_TABLE_ELEMS,
126 CFG_TGT_DEFAULT_MCAST2UCAST_MODE,
127 CFG_TGT_DEFAULT_TX_DBG_LOG_SIZE,
128 CFG_TGT_WDS_ENTRIES,
129 CFG_TGT_DEFAULT_DMA_BURST_SIZE,
130 CFG_TGT_DEFAULT_MAC_AGGR_DELIM,
131 CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK,
132 CFG_TGT_DEFAULT_VOW_CONFIG,
133 CFG_TGT_DEFAULT_GTK_OFFLOAD_MAX_VDEV,
134 CFG_TGT_NUM_MSDU_DESC,
135 CFG_TGT_MAX_FRAG_TABLE_ENTRIES,
136 CFG_TGT_NUM_TDLS_VDEVS,
137 CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES,
138 CFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV,
139 CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES,
140 0,
141 0,
142 0,
143 CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS,
144 CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS,
145 0,
146 CFG_TGT_NUM_OCB_VDEVS,
147 CFG_TGT_NUM_OCB_CHANNELS,
148 CFG_TGT_NUM_OCB_SCHEDULES,
149 };
150
151 /* Update the max number of peers */
152 scn = cds_get_context(CDF_MODULE_ID_HIF);
153 if (!scn) {
154 WMA_LOGE("%s: cds_context is NULL", __func__);
155 return;
156 }
157 no_of_peers_supported = ol_get_number_of_peers_supported(scn);
158 tgt_cfg.num_peers = no_of_peers_supported + CFG_TGT_NUM_VDEV + 2;
159 tgt_cfg.num_tids = (2 * (no_of_peers_supported + CFG_TGT_NUM_VDEV + 2));
160 tgt_cfg.scan_max_pending_req = wma_handle->max_scan;
161
162 WMITLV_SET_HDR(&tgt_cfg.tlv_header,
163 WMITLV_TAG_STRUC_wmi_resource_config,
164 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config));
165 /* reduce the peer/vdev if CFG_TGT_NUM_MSDU_DESC exceeds 1000 */
166#ifdef PERE_IP_HDR_ALIGNMENT_WAR
167 if (scn->host_80211_enable) {
168 /*
169 * To make the IP header begins at dword aligned address,
170 * we make the decapsulation mode as Native Wifi.
171 */
172 tgt_cfg.rx_decap_mode = CFG_TGT_RX_DECAP_MODE_NWIFI;
173 }
174#endif /* PERE_IP_HDR_ALIGNMENT_WAR */
175 wma_handle->wlan_resource_config = tgt_cfg;
176}
177
178/**
179 * wma_cli_get_command() - WMA "get" command processor
180 * @vdev_id: virtual device for the command
181 * @param_id: parameter id
182 * @vpdev: parameter category
183 *
184 * Return: parameter value on success, -EINVAL on failure
185 */
186int wma_cli_get_command(int vdev_id, int param_id, int vpdev)
187{
188 int ret = 0;
189 tp_wma_handle wma;
190 struct wma_txrx_node *intr = NULL;
191
192 wma = cds_get_context(CDF_MODULE_ID_WMA);
193
194 if (NULL == wma) {
195 WMA_LOGE("%s: Invalid wma handle", __func__);
196 return -EINVAL;
197 }
198
199 intr = wma->interfaces;
200
201 if (VDEV_CMD == vpdev) {
202 switch (param_id) {
203 case WMI_VDEV_PARAM_NSS:
204 ret = intr[vdev_id].config.nss;
205 break;
206#ifdef QCA_SUPPORT_GTX
207 case WMI_VDEV_PARAM_GTX_HT_MCS:
208 ret = intr[vdev_id].config.gtx_info.gtxRTMask[0];
209 break;
210 case WMI_VDEV_PARAM_GTX_VHT_MCS:
211 ret = intr[vdev_id].config.gtx_info.gtxRTMask[1];
212 break;
213 case WMI_VDEV_PARAM_GTX_USR_CFG:
214 ret = intr[vdev_id].config.gtx_info.gtxUsrcfg;
215 break;
216 case WMI_VDEV_PARAM_GTX_THRE:
217 ret = intr[vdev_id].config.gtx_info.gtxPERThreshold;
218 break;
219 case WMI_VDEV_PARAM_GTX_MARGIN:
220 ret = intr[vdev_id].config.gtx_info.gtxPERMargin;
221 break;
222 case WMI_VDEV_PARAM_GTX_STEP:
223 ret = intr[vdev_id].config.gtx_info.gtxTPCstep;
224 break;
225 case WMI_VDEV_PARAM_GTX_MINTPC:
226 ret = intr[vdev_id].config.gtx_info.gtxTPCMin;
227 break;
228 case WMI_VDEV_PARAM_GTX_BW_MASK:
229 ret = intr[vdev_id].config.gtx_info.gtxBWMask;
230 break;
231#endif /* QCA_SUPPORT_GTX */
232 case WMI_VDEV_PARAM_LDPC:
233 ret = intr[vdev_id].config.ldpc;
234 break;
235 case WMI_VDEV_PARAM_TX_STBC:
236 ret = intr[vdev_id].config.tx_stbc;
237 break;
238 case WMI_VDEV_PARAM_RX_STBC:
239 ret = intr[vdev_id].config.rx_stbc;
240 break;
241 case WMI_VDEV_PARAM_SGI:
242 ret = intr[vdev_id].config.shortgi;
243 break;
244 case WMI_VDEV_PARAM_ENABLE_RTSCTS:
245 ret = intr[vdev_id].config.rtscts_en;
246 break;
247 case WMI_VDEV_PARAM_CHWIDTH:
248 ret = intr[vdev_id].config.chwidth;
249 break;
250 case WMI_VDEV_PARAM_FIXED_RATE:
251 ret = intr[vdev_id].config.tx_rate;
252 break;
253 default:
254 WMA_LOGE("Invalid cli_get vdev command/Not"
255 " yet implemented 0x%x", param_id);
256 return -EINVAL;
257 }
258 } else if (PDEV_CMD == vpdev) {
259 switch (param_id) {
260 case WMI_PDEV_PARAM_ANI_ENABLE:
261 ret = wma->pdevconfig.ani_enable;
262 break;
263 case WMI_PDEV_PARAM_ANI_POLL_PERIOD:
264 ret = wma->pdevconfig.ani_poll_len;
265 break;
266 case WMI_PDEV_PARAM_ANI_LISTEN_PERIOD:
267 ret = wma->pdevconfig.ani_listen_len;
268 break;
269 case WMI_PDEV_PARAM_ANI_OFDM_LEVEL:
270 ret = wma->pdevconfig.ani_ofdm_level;
271 break;
272 case WMI_PDEV_PARAM_ANI_CCK_LEVEL:
273 ret = wma->pdevconfig.ani_cck_level;
274 break;
275 case WMI_PDEV_PARAM_DYNAMIC_BW:
276 ret = wma->pdevconfig.cwmenable;
277 break;
278 case WMI_PDEV_PARAM_CTS_CBW:
279 ret = wma->pdevconfig.cts_cbw;
280 break;
281 case WMI_PDEV_PARAM_TX_CHAIN_MASK:
282 ret = wma->pdevconfig.txchainmask;
283 break;
284 case WMI_PDEV_PARAM_RX_CHAIN_MASK:
285 ret = wma->pdevconfig.rxchainmask;
286 break;
287 case WMI_PDEV_PARAM_TXPOWER_LIMIT2G:
288 ret = wma->pdevconfig.txpow2g;
289 break;
290 case WMI_PDEV_PARAM_TXPOWER_LIMIT5G:
291 ret = wma->pdevconfig.txpow5g;
292 break;
293 case WMI_PDEV_PARAM_POWER_GATING_SLEEP:
294 ret = wma->pdevconfig.pwrgating;
295 break;
296 case WMI_PDEV_PARAM_BURST_ENABLE:
297 ret = wma->pdevconfig.burst_enable;
298 break;
299 case WMI_PDEV_PARAM_BURST_DUR:
300 ret = wma->pdevconfig.burst_dur;
301 break;
302 default:
303 WMA_LOGE("Invalid cli_get pdev command/Not"
304 " yet implemented 0x%x", param_id);
305 return -EINVAL;
306 }
307 } else if (GEN_CMD == vpdev) {
308 switch (param_id) {
309 case GEN_VDEV_PARAM_AMPDU:
310 ret = intr[vdev_id].config.ampdu;
311 break;
312 case GEN_VDEV_PARAM_AMSDU:
313 ret = intr[vdev_id].config.amsdu;
314 break;
315 default:
316 WMA_LOGE("Invalid generic vdev command/Not"
317 " yet implemented 0x%x", param_id);
318 return -EINVAL;
319 }
320 } else if (PPS_CMD == vpdev) {
321 switch (param_id) {
322 case WMI_VDEV_PPS_PAID_MATCH:
323 ret = intr[vdev_id].config.pps_params.paid_match_enable;
324 break;
325 case WMI_VDEV_PPS_GID_MATCH:
326 ret = intr[vdev_id].config.pps_params.gid_match_enable;
327 break;
328 case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
329 ret = intr[vdev_id].config.pps_params.tim_clear;
330 break;
331 case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
332 ret = intr[vdev_id].config.pps_params.dtim_clear;
333 break;
334 case WMI_VDEV_PPS_EOF_PAD_DELIM:
335 ret = intr[vdev_id].config.pps_params.eof_delim;
336 break;
337 case WMI_VDEV_PPS_MACADDR_MISMATCH:
338 ret = intr[vdev_id].config.pps_params.mac_match;
339 break;
340 case WMI_VDEV_PPS_DELIM_CRC_FAIL:
341 ret = intr[vdev_id].config.pps_params.delim_fail;
342 break;
343 case WMI_VDEV_PPS_GID_NSTS_ZERO:
344 ret = intr[vdev_id].config.pps_params.nsts_zero;
345 break;
346 case WMI_VDEV_PPS_RSSI_CHECK:
347 ret = intr[vdev_id].config.pps_params.rssi_chk;
348 break;
349 default:
350 WMA_LOGE("Invalid pps vdev command/Not"
351 " yet implemented 0x%x", param_id);
352 return -EINVAL;
353 }
354 } else if (QPOWER_CMD == vpdev) {
355 switch (param_id) {
356 case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT:
357 ret = intr[vdev_id].config.qpower_params.
358 max_ps_poll_cnt;
359 break;
360 case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE:
361 ret = intr[vdev_id].config.qpower_params.
362 max_tx_before_wake;
363 break;
364 case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
365 ret = intr[vdev_id].config.qpower_params.
366 spec_ps_poll_wake_interval;
367 break;
368 case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
369 ret = intr[vdev_id].config.qpower_params.
370 max_spec_nodata_ps_poll;
371 break;
372 default:
373 WMA_LOGE("Invalid generic vdev command/Not"
374 " yet implemented 0x%x", param_id);
375 return -EINVAL;
376 }
377 } else if (GTX_CMD == vpdev) {
378 switch (param_id) {
379 case WMI_VDEV_PARAM_GTX_HT_MCS:
380 ret = intr[vdev_id].config.gtx_info.gtxRTMask[0];
381 break;
382 case WMI_VDEV_PARAM_GTX_VHT_MCS:
383 ret = intr[vdev_id].config.gtx_info.gtxRTMask[1];
384 break;
385 case WMI_VDEV_PARAM_GTX_USR_CFG:
386 ret = intr[vdev_id].config.gtx_info.gtxUsrcfg;
387 break;
388 case WMI_VDEV_PARAM_GTX_THRE:
389 ret = intr[vdev_id].config.gtx_info.gtxPERThreshold;
390 break;
391 case WMI_VDEV_PARAM_GTX_MARGIN:
392 ret = intr[vdev_id].config.gtx_info.gtxPERMargin;
393 break;
394 case WMI_VDEV_PARAM_GTX_STEP:
395 ret = intr[vdev_id].config.gtx_info.gtxTPCstep;
396 break;
397 case WMI_VDEV_PARAM_GTX_MINTPC:
398 ret = intr[vdev_id].config.gtx_info.gtxTPCMin;
399 break;
400 case WMI_VDEV_PARAM_GTX_BW_MASK:
401 ret = intr[vdev_id].config.gtx_info.gtxBWMask;
402 break;
403 default:
404 WMA_LOGE("Invalid generic vdev command/Not"
405 " yet implemented 0x%x", param_id);
406 return -EINVAL;
407 }
408 }
409 return ret;
410}
411
412/**
413 * wma_cli_set2_command() - WMA "set 2 params" command processor
414 * @vdev_id: virtual device for the command
415 * @param_id: parameter id
416 * @sval1: first parameter value
417 * @sval2: second parameter value
418 * @vpdev: parameter category
419 *
420 * Command handler for set operations which require 2 parameters
421 *
422 * Return: 0 on success, errno on failure
423 */
424int wma_cli_set2_command(int vdev_id, int param_id, int sval1,
425 int sval2, int vpdev)
426{
427 cds_msg_t msg = { 0 };
428 wma_cli_set_cmd_t *iwcmd;
429
430 iwcmd = cdf_mem_malloc(sizeof(*iwcmd));
431 if (!iwcmd) {
432 WMA_LOGE("%s: Failed alloc memory for iwcmd", __func__);
433 return -ENOMEM;
434 }
435
436 cdf_mem_zero(iwcmd, sizeof(*iwcmd));
437 iwcmd->param_value = sval1;
438 iwcmd->param_sec_value = sval2;
439 iwcmd->param_vdev_id = vdev_id;
440 iwcmd->param_id = param_id;
441 iwcmd->param_vp_dev = vpdev;
442 msg.type = WMA_CLI_SET_CMD;
443 msg.reserved = 0;
444 msg.bodyptr = iwcmd;
445
446 if (CDF_STATUS_SUCCESS !=
447 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
448 WMA_LOGP("%s: Failed to post WMA_CLI_SET_CMD msg",
449 __func__);
450 cdf_mem_free(iwcmd);
451 return -EIO;
452 }
453 return 0;
454}
455
456/**
457 * wma_cli_set_command() - WMA "set" command processor
458 * @vdev_id: virtual device for the command
459 * @param_id: parameter id
460 * @sval: parameter value
461 * @vpdev: parameter category
462 *
463 * Command handler for set operations
464 *
465 * Return: 0 on success, errno on failure
466 */
467int wma_cli_set_command(int vdev_id, int param_id, int sval, int vpdev)
468{
469 return wma_cli_set2_command(vdev_id, param_id, sval, 0, vpdev);
470
471}
472
473/**
474 * wma_set_priv_cfg() - set private config parameters
475 * @wma_handle: wma handle
476 * @privcmd: private command
477 *
478 * Return: 0 for success or error code
479 */
480static int32_t wma_set_priv_cfg(tp_wma_handle wma_handle,
481 wma_cli_set_cmd_t *privcmd)
482{
483 int32_t ret = 0;
484
485 switch (privcmd->param_id) {
486 case WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID:
487 ret = wma_set_txrx_fw_stats_level(wma_handle,
488 privcmd->param_vdev_id,
489 privcmd->param_value);
490 break;
491 case WMA_VDEV_TXRX_FWSTATS_RESET_CMDID:
492 ret = wma_txrx_fw_stats_reset(wma_handle,
493 privcmd->param_vdev_id,
494 privcmd->param_value);
495 break;
496 case WMI_STA_SMPS_FORCE_MODE_CMDID:
497 wma_set_mimops(wma_handle, privcmd->param_vdev_id,
498 privcmd->param_value);
499 break;
500 case WMI_STA_SMPS_PARAM_CMDID:
501 wma_set_smps_params(wma_handle, privcmd->param_vdev_id,
502 privcmd->param_value);
503 break;
504 case WMA_VDEV_MCC_SET_TIME_LATENCY:
505 {
506 /* Extract first MCC adapter/vdev channel number and latency */
507 uint8_t mcc_channel = privcmd->param_value & 0x000000FF;
508 uint8_t mcc_channel_latency =
509 (privcmd->param_value & 0x0000FF00) >> 8;
510 int ret = -1;
511 WMA_LOGD("%s: Parsed input: Channel #1:%d, latency:%dms",
512 __func__, mcc_channel, mcc_channel_latency);
513 ret = wma_set_mcc_channel_time_latency(wma_handle,
514 mcc_channel,
515 mcc_channel_latency);
516 }
517 break;
518 case WMA_VDEV_MCC_SET_TIME_QUOTA:
519 {
520 /* Extract the MCC 2 adapters/vdevs channel numbers and time
521 * quota value for the first adapter only (which is specified
522 * in iwpriv command.
523 */
524 uint8_t adapter_2_chan_number =
525 privcmd->param_value & 0x000000FF;
526 uint8_t adapter_1_chan_number =
527 (privcmd->param_value & 0x0000FF00) >> 8;
528 uint8_t adapter_1_quota =
529 (privcmd->param_value & 0x00FF0000) >> 16;
530 int ret = -1;
531
532 WMA_LOGD("%s: Parsed input: Channel #1:%d, Channel #2:%d, quota 1:%dms",
533 __func__, adapter_1_chan_number,
534 adapter_2_chan_number, adapter_1_quota);
535
536 ret = wma_set_mcc_channel_time_quota(wma_handle,
537 adapter_1_chan_number,
538 adapter_1_quota,
539 adapter_2_chan_number);
540 }
541 break;
542 case WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE:
543 {
544 wma_handle->wma_ibss_power_save_params.atimWindowLength =
545 privcmd->param_value;
546 WMA_LOGD("%s: IBSS power save ATIM Window = %d",
547 __func__, wma_handle->wma_ibss_power_save_params.
548 atimWindowLength);
549 }
550 break;
551 case WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED:
552 {
553 wma_handle->wma_ibss_power_save_params.isPowerSaveAllowed =
554 privcmd->param_value;
555 WMA_LOGD("%s: IBSS is Power Save Allowed = %d",
556 __func__, wma_handle->wma_ibss_power_save_params.
557 isPowerSaveAllowed);
558 }
559 break;
560 case WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED:
561 {
562 wma_handle->wma_ibss_power_save_params. isPowerCollapseAllowed =
563 privcmd->param_value;
564 WMA_LOGD("%s: IBSS is Power Collapse Allowed = %d",
565 __func__, wma_handle->wma_ibss_power_save_params.
566 isPowerCollapseAllowed);
567 }
568 break;
569 case WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX:
570 {
571 wma_handle->wma_ibss_power_save_params.isAwakeonTxRxEnabled =
572 privcmd->param_value;
573 WMA_LOGD("%s: IBSS Power Save Awake on Tx/Rx Enabled = %d",
574 __func__, wma_handle->wma_ibss_power_save_params.
575 isAwakeonTxRxEnabled);
576 }
577 break;
578 case WMA_VDEV_IBSS_SET_INACTIVITY_TIME:
579 {
580 wma_handle->wma_ibss_power_save_params.inactivityCount =
581 privcmd->param_value;
582 WMA_LOGD("%s: IBSS Power Save Data Inactivity Count = %d",
583 __func__, wma_handle->wma_ibss_power_save_params.
584 inactivityCount);
585 }
586 break;
587 case WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME:
588 {
589 wma_handle->wma_ibss_power_save_params.txSPEndInactivityTime =
590 privcmd->param_value;
591 WMA_LOGD("%s: IBSS Power Save Transmit EOSP inactivity time out = %d",
592 __func__, wma_handle->wma_ibss_power_save_params.
593 txSPEndInactivityTime);
594 }
595 break;
596 case WMA_VDEV_DFS_CONTROL_CMDID:
597 {
598 struct ieee80211com *dfs_ic = wma_handle->dfs_ic;
599 struct ath_dfs *dfs;
600
601 if (!dfs_ic) {
602 ret = -ENOENT;
603 } else {
604 if (dfs_ic->ic_curchan) {
605 WMA_LOGD("%s: Debug cmd: %s received on ch: %d",
606 __func__, "WMA_VDEV_DFS_CONTROL_CMDID",
607 dfs_ic->ic_curchan->ic_ieee);
608
609 if (dfs_ic->ic_curchan->ic_flagext &
610 IEEE80211_CHAN_DFS) {
611 dfs = (struct ath_dfs *)dfs_ic->ic_dfs;
612 dfs->dfs_bangradar = 1;
613 dfs->ath_radar_tasksched = 1;
614 OS_SET_TIMER(&dfs->ath_dfs_task_timer,
615 0);
616 } else {
617 ret = -ENOENT;
618 }
619 } else {
620 ret = -ENOENT;
621 }
622 }
623
624 if (ret == -ENOENT) {
625 WMA_LOGE("%s: Operating channel is not DFS capable,ignoring %s",
626 __func__, "WMA_VDEV_DFS_CONTROL_CMDID");
627 } else if (ret) {
628 WMA_LOGE("%s: Sending command %s failed with %d\n",
629 __func__, "WMA_VDEV_DFS_CONTROL_CMDID",
630 ret);
631 }
632 }
633 break;
634 case WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS:
635 {
636 wma_handle->wma_ibss_power_save_params.ibssPsWarmupTime =
637 privcmd->param_value;
638 WMA_LOGD("%s: IBSS Power Save Warm Up Time in Seconds = %d",
639 __func__, wma_handle->wma_ibss_power_save_params.
640 ibssPsWarmupTime);
641 }
642 break;
643 case WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW:
644 {
645 wma_handle->wma_ibss_power_save_params.ibssPs1RxChainInAtimEnable
646 = privcmd->param_value;
647 WMA_LOGD("%s: IBSS Power Save single RX Chain Enable In ATIM = %d",
648 __func__, wma_handle->wma_ibss_power_save_params.
649 ibssPs1RxChainInAtimEnable);
650 }
651 break;
652
653 case WMA_VDEV_TXRX_GET_IPA_UC_FW_STATS_CMDID:
654 {
655 ol_txrx_pdev_handle pdev;
656
657 pdev = cds_get_context(CDF_MODULE_ID_TXRX);
658 if (!pdev) {
659 WMA_LOGE("pdev NULL for uc stat");
660 return -EINVAL;
661 }
662 ol_txrx_ipa_uc_get_stat(pdev);
663 }
664 break;
665
666 default:
667 WMA_LOGE("Invalid wma config command id:%d", privcmd->param_id);
668 ret = -EINVAL;
669 }
670 return ret;
671}
672
673/**
674 * wmi_unified_pdev_set_param() - set pdev parameters
675 * @wmi_handle: wmi handle
676 * @param_id: parameter id
677 * @param_value: parameter value
678 *
679 * Return: 0 on success, errno on failure
680 */
681int
682wmi_unified_pdev_set_param(wmi_unified_t wmi_handle, WMI_PDEV_PARAM param_id,
683 uint32_t param_value)
684{
685 int ret;
686 wmi_pdev_set_param_cmd_fixed_param *cmd;
687 wmi_buf_t buf;
688 uint16_t len = sizeof(*cmd);
689
690 buf = wmi_buf_alloc(wmi_handle, len);
691 if (!buf) {
692 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
693 return -ENOMEM;
694 }
695 cmd = (wmi_pdev_set_param_cmd_fixed_param *) wmi_buf_data(buf);
696 WMITLV_SET_HDR(&cmd->tlv_header,
697 WMITLV_TAG_STRUC_wmi_pdev_set_param_cmd_fixed_param,
698 WMITLV_GET_STRUCT_TLVLEN
699 (wmi_pdev_set_param_cmd_fixed_param));
700 cmd->reserved0 = 0;
701 cmd->param_id = param_id;
702 cmd->param_value = param_value;
703 WMA_LOGD("Setting pdev param = %x, value = %u", param_id, param_value);
704 ret = wmi_unified_cmd_send(wmi_handle, buf, len,
705 WMI_PDEV_SET_PARAM_CMDID);
706 if (ret != EOK) {
707 WMA_LOGE("Failed to send set param command ret = %d", ret);
708 wmi_buf_free(buf);
709 }
710 return ret;
711}
712
713/**
714 * wma_set_modulated_dtim() - function to configure modulated dtim
715 * @wma: wma handle
716 * @privcmd: structure containing parameters
717 *
718 * This function configures the modulated dtim in firmware
719 *
720 * Return: none
721 */
722static void wma_set_modulated_dtim(tp_wma_handle wma,
723 wma_cli_set_cmd_t *privcmd)
724{
725 uint8_t vdev_id = privcmd->param_vdev_id;
726 struct wma_txrx_node *iface =
727 &wma->interfaces[vdev_id];
728 bool prev_dtim_enabled;
729 uint32_t listen_interval;
730 int ret;
731
732 iface->alt_modulated_dtim = privcmd->param_value;
733
734 prev_dtim_enabled = iface->alt_modulated_dtim_enabled;
735
736 if (1 != privcmd->param_value)
737 iface->alt_modulated_dtim_enabled = true;
738 else
739 iface->alt_modulated_dtim_enabled = false;
740
741 if ((true == iface->alt_modulated_dtim_enabled) ||
742 (true == prev_dtim_enabled)) {
743
744 listen_interval = iface->alt_modulated_dtim
745 * iface->dtimPeriod;
746
747 ret = wmi_unified_vdev_set_param_send(wma->wmi_handle,
748 privcmd->param_vdev_id,
749 WMI_VDEV_PARAM_LISTEN_INTERVAL,
750 listen_interval);
751 if (ret)
752 /* Even if it fails, continue */
753 WMA_LOGW("Failed to set listen interval %d",
754 listen_interval);
755
756 ret = wmi_unified_vdev_set_param_send(wma->wmi_handle,
757 privcmd->param_vdev_id,
758 WMI_VDEV_PARAM_DTIM_POLICY ,
759 NORMAL_DTIM);
760 if (ret)
761 WMA_LOGE("Failed to Set to Normal DTIM policy");
762 }
763}
764
765
766/**
767 * wma_process_cli_set_cmd() - set parameters to fw
768 * @wma: wma handle
769 * @privcmd: command
770 *
771 * Return: none
772 */
773static void wma_process_cli_set_cmd(tp_wma_handle wma,
774 wma_cli_set_cmd_t *privcmd)
775{
776 int ret = 0, vid = privcmd->param_vdev_id, pps_val = 0;
777 struct wma_txrx_node *intr = wma->interfaces;
778 tpAniSirGlobal pMac = cds_get_context(CDF_MODULE_ID_PE);
779 struct qpower_params *qparams = &intr[vid].config.qpower_params;
780
781 WMA_LOGD("wmihandle %p", wma->wmi_handle);
782
783 if (NULL == pMac) {
784 WMA_LOGE("%s: Failed to get pMac", __func__);
785 return;
786 }
787
788 if (privcmd->param_id >= WMI_CMDID_MAX) {
789 /*
790 * This configuration setting is not done using any wmi
791 * command, call appropriate handler.
792 */
793 if (wma_set_priv_cfg(wma, privcmd))
794 WMA_LOGE("Failed to set wma priv congiuration");
795 return;
796 }
797
798 switch (privcmd->param_vp_dev) {
799 case VDEV_CMD:
800 WMA_LOGD("vdev id %d pid %d pval %d", privcmd->param_vdev_id,
801 privcmd->param_id, privcmd->param_value);
802 ret = wmi_unified_vdev_set_param_send(wma->wmi_handle,
803 privcmd->param_vdev_id,
804 privcmd->param_id,
805 privcmd->param_value);
806 if (ret) {
807 WMA_LOGE("wmi_unified_vdev_set_param_send failed ret %d",
808 ret);
809 return;
810 }
811 break;
812 case PDEV_CMD:
813 WMA_LOGD("pdev pid %d pval %d", privcmd->param_id,
814 privcmd->param_value);
815 if ((privcmd->param_id == WMI_PDEV_PARAM_RX_CHAIN_MASK) ||
816 (privcmd->param_id == WMI_PDEV_PARAM_TX_CHAIN_MASK)) {
817 wma_update_txrx_chainmask(wma->num_rf_chains,
818 &privcmd->param_value);
819 }
820 ret = wmi_unified_pdev_set_param(wma->wmi_handle,
821 privcmd->param_id,
822 privcmd->param_value);
823 if (ret) {
824 WMA_LOGE("wmi_unified_vdev_set_param_send failed ret %d",
825 ret);
826 return;
827 }
828 break;
829 case GEN_CMD:
830 {
831 ol_txrx_vdev_handle vdev = NULL;
832 struct wma_txrx_node *intr = wma->interfaces;
833
834 vdev = wma_find_vdev_by_id(wma, privcmd->param_vdev_id);
835 if (!vdev) {
836 WMA_LOGE("%s:Invalid vdev handle", __func__);
837 return;
838 }
839
840 WMA_LOGD("gen pid %d pval %d", privcmd->param_id,
841 privcmd->param_value);
842
843 switch (privcmd->param_id) {
844 case GEN_VDEV_PARAM_AMPDU:
845 ret = ol_txrx_aggr_cfg(vdev, privcmd->param_value, 0);
846 if (ret)
847 WMA_LOGE("ol_txrx_aggr_cfg set ampdu failed ret %d",
848 ret);
849 else
850 intr[privcmd->param_vdev_id].config.ampdu =
851 privcmd->param_value;
852 break;
853 case GEN_VDEV_PARAM_AMSDU:
854 ret = ol_txrx_aggr_cfg(vdev, 0, privcmd->param_value);
855 if (ret)
856 WMA_LOGE("ol_txrx_aggr_cfg set amsdu failed ret %d",
857 ret);
858 else
859 intr[privcmd->param_vdev_id].config.
860 amsdu = privcmd->param_value;
861 break;
862 case GEN_PARAM_DUMP_AGC_START:
863 htc_dump(wma->htc_handle, AGC_DUMP, true);
864 break;
865 case GEN_PARAM_DUMP_AGC:
866 htc_dump(wma->htc_handle, AGC_DUMP, false);
867 break;
868 case GEN_PARAM_DUMP_CHANINFO_START:
869 htc_dump(wma->htc_handle, CHAN_DUMP, true);
870 break;
871 case GEN_PARAM_DUMP_CHANINFO:
872 htc_dump(wma->htc_handle, CHAN_DUMP, false);
873 break;
874 case GEN_PARAM_DUMP_WATCHDOG:
875 htc_dump(wma->htc_handle, WD_DUMP, false);
876 break;
877 case GEN_PARAM_CRASH_INJECT:
878 ret = wmi_crash_inject(wma->wmi_handle,
879 privcmd->param_value,
880 privcmd->param_sec_value);
881 break;
882#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
883 case GEN_PARAM_DUMP_PCIE_ACCESS_LOG:
884 htc_dump(wma->htc_handle, PCIE_DUMP, false);
885 break;
886#endif /* CONFIG_ATH_PCIE_ACCESS_DEBUG */
887 case GEN_PARAM_MODULATED_DTIM:
888 wma_set_modulated_dtim(wma, privcmd);
889 break;
890 default:
891 WMA_LOGE("Invalid param id 0x%x",
892 privcmd->param_id);
893 break;
894 }
895 break;
896 }
897 case DBG_CMD:
898 WMA_LOGD("dbg pid %d pval %d", privcmd->param_id,
899 privcmd->param_value);
900 switch (privcmd->param_id) {
901 case WMI_DBGLOG_LOG_LEVEL:
902 ret = dbglog_set_log_lvl(wma->wmi_handle,
903 privcmd->param_value);
904 if (ret)
905 WMA_LOGE("dbglog_set_log_lvl failed ret %d",
906 ret);
907 break;
908 case WMI_DBGLOG_VAP_ENABLE:
909 ret = dbglog_vap_log_enable(wma->wmi_handle,
910 privcmd->param_value, true);
911 if (ret)
912 WMA_LOGE("dbglog_vap_log_enable failed ret %d",
913 ret);
914 break;
915 case WMI_DBGLOG_VAP_DISABLE:
916 ret = dbglog_vap_log_enable(wma->wmi_handle,
917 privcmd->param_value, false);
918 if (ret)
919 WMA_LOGE("dbglog_vap_log_enable failed ret %d",
920 ret);
921 break;
922 case WMI_DBGLOG_MODULE_ENABLE:
923 ret = dbglog_module_log_enable(wma->wmi_handle,
924 privcmd->param_value, true);
925 if (ret)
926 WMA_LOGE("dbglog_module_log_enable failed ret %d",
927 ret);
928 break;
929 case WMI_DBGLOG_MODULE_DISABLE:
930 ret = dbglog_module_log_enable(wma->wmi_handle,
931 privcmd->param_value, false);
932 if (ret)
933 WMA_LOGE("dbglog_module_log_enable failed ret %d",
934 ret);
935 break;
936 case WMI_DBGLOG_MOD_LOG_LEVEL:
937 ret = dbglog_set_mod_log_lvl(wma->wmi_handle,
938 privcmd->param_value);
939 if (ret)
940 WMA_LOGE("dbglog_module_log_enable failed ret %d",
941 ret);
942 break;
943 case WMI_DBGLOG_TYPE:
944 ret = dbglog_parser_type_init(wma->wmi_handle,
945 privcmd->param_value);
946 if (ret)
947 WMA_LOGE("dbglog_parser_type_init failed ret %d",
948 ret);
949 break;
950 case WMI_DBGLOG_REPORT_ENABLE:
951 ret = dbglog_report_enable(wma->wmi_handle,
952 privcmd->param_value);
953 if (ret)
954 WMA_LOGE("dbglog_report_enable failed ret %d",
955 ret);
956 break;
957#ifdef FEATURE_GREEN_AP
958 case WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID:
959 /* Set the Green AP */
960 ret = wmi_unified_pdev_green_ap_ps_enable_cmd
961 (wma->wmi_handle, privcmd->param_value);
962 if (ret) {
963 WMA_LOGE("Set GreenAP Failed val %d",
964 privcmd->param_value);
965 }
966 break;
967#endif /* FEATURE_GREEN_AP */
968
969 default:
970 WMA_LOGE("Invalid param id 0x%x", privcmd->param_id);
971 break;
972 }
973 break;
974 case PPS_CMD:
975 WMA_LOGD("dbg pid %d pval %d", privcmd->param_id,
976 privcmd->param_value);
977 switch (privcmd->param_id) {
978
979 case WMI_VDEV_PPS_PAID_MATCH:
980 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
981 (PKT_PWR_SAVE_PAID_MATCH & 0xffff);
982 intr[vid].config.pps_params.paid_match_enable =
983 privcmd->param_value;
984 break;
985 case WMI_VDEV_PPS_GID_MATCH:
986 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
987 (PKT_PWR_SAVE_GID_MATCH & 0xffff);
988 intr[vid].config.pps_params.gid_match_enable =
989 privcmd->param_value;
990 break;
991 case WMI_VDEV_PPS_EARLY_TIM_CLEAR:
992 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
993 (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff);
994 intr[vid].config.pps_params.tim_clear =
995 privcmd->param_value;
996 break;
997 case WMI_VDEV_PPS_EARLY_DTIM_CLEAR:
998 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
999 (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff);
1000 intr[vid].config.pps_params.dtim_clear =
1001 privcmd->param_value;
1002 break;
1003 case WMI_VDEV_PPS_EOF_PAD_DELIM:
1004 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1005 (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff);
1006 intr[vid].config.pps_params.eof_delim =
1007 privcmd->param_value;
1008 break;
1009 case WMI_VDEV_PPS_MACADDR_MISMATCH:
1010 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1011 (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff);
1012 intr[vid].config.pps_params.mac_match =
1013 privcmd->param_value;
1014 break;
1015 case WMI_VDEV_PPS_DELIM_CRC_FAIL:
1016 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1017 (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff);
1018 intr[vid].config.pps_params.delim_fail =
1019 privcmd->param_value;
1020 break;
1021 case WMI_VDEV_PPS_GID_NSTS_ZERO:
1022 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1023 (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff);
1024 intr[vid].config.pps_params.nsts_zero =
1025 privcmd->param_value;
1026 break;
1027 case WMI_VDEV_PPS_RSSI_CHECK:
1028 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1029 (PKT_PWR_SAVE_RSSI_CHECK & 0xffff);
1030 intr[vid].config.pps_params.rssi_chk =
1031 privcmd->param_value;
1032 break;
1033 case WMI_VDEV_PPS_5G_EBT:
1034 pps_val = ((privcmd->param_value << 31) & 0xffff0000) |
1035 (PKT_PWR_SAVE_5G_EBT & 0xffff);
1036 intr[vid].config.pps_params.ebt_5g =
1037 privcmd->param_value;
1038 break;
1039 default:
1040 WMA_LOGE("Invalid param id 0x%x", privcmd->param_id);
1041 break;
1042 }
1043 break;
1044
1045 case QPOWER_CMD:
1046 WMA_LOGD("QPOWER CLI CMD pid %d pval %d", privcmd->param_id,
1047 privcmd->param_value);
1048 switch (privcmd->param_id) {
1049 case WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT:
1050 WMA_LOGD("QPOWER CLI CMD:Ps Poll Cnt val %d",
1051 privcmd->param_value);
1052 /* Set the QPower Ps Poll Count */
1053 ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
1054 vid, WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
1055 privcmd->param_value);
1056 if (ret) {
1057 WMA_LOGE("Set Q-PsPollCnt Failed vdevId %d val %d",
1058 vid, privcmd->param_value);
1059 } else {
1060 qparams->max_ps_poll_cnt = privcmd->param_value;
1061 }
1062 break;
1063 case WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE:
1064 WMA_LOGD("QPOWER CLI CMD:Max Tx Before wake val %d",
1065 privcmd->param_value);
1066 /* Set the QPower Max Tx Before Wake */
1067 ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
1068 vid, WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
1069 privcmd->param_value);
1070 if (ret) {
1071 WMA_LOGE("Set Q-MaxTxBefWake Failed vId %d val %d",
1072 vid, privcmd->param_value);
1073 } else {
1074 qparams->max_tx_before_wake =
1075 privcmd->param_value;
1076 }
1077 break;
1078 case WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
1079 WMA_LOGD("QPOWER CLI CMD:Ps Poll Wake Inv val %d",
1080 privcmd->param_value);
1081 /* Set the QPower Spec Ps Poll Wake Inv */
1082 ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
1083 vid, WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
1084 privcmd->param_value);
1085 if (ret) {
1086 WMA_LOGE("Set Q-PsPoll WakeIntv Failed vId %d val %d",
1087 vid, privcmd->param_value);
1088 } else {
1089 qparams->spec_ps_poll_wake_interval =
1090 privcmd->param_value;
1091 }
1092 break;
1093 case WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
1094 WMA_LOGD("QPOWER CLI CMD:Spec NoData Ps Poll val %d",
1095 privcmd->param_value);
1096 /* Set the QPower Spec NoData PsPoll */
1097 ret = wmi_unified_set_sta_ps_param(wma->wmi_handle,
1098 vid, WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
1099 privcmd->param_value);
1100 if (ret) {
1101 WMA_LOGE("Set Q-SpecNoDataPsPoll Failed vId %d val %d",
1102 vid, privcmd->param_value);
1103 } else {
1104 qparams->max_spec_nodata_ps_poll =
1105 privcmd->param_value;
1106 }
1107 break;
1108
1109 default:
1110 WMA_LOGE("Invalid param id 0x%x", privcmd->param_id);
1111 break;
1112 }
1113 break;
1114 case GTX_CMD:
1115 WMA_LOGD("vdev id %d pid %d pval %d", privcmd->param_vdev_id,
1116 privcmd->param_id, privcmd->param_value);
1117 switch (privcmd->param_id) {
1118 case WMI_VDEV_PARAM_GTX_HT_MCS:
1119 intr[vid].config.gtx_info.gtxRTMask[0] =
1120 privcmd->param_value;
1121 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1122 privcmd->param_vdev_id,
1123 &intr[vid].config.gtx_info);
1124 break;
1125 case WMI_VDEV_PARAM_GTX_VHT_MCS:
1126 intr[vid].config.gtx_info.gtxRTMask[1] =
1127 privcmd->param_value;
1128 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1129 privcmd->param_vdev_id,
1130 &intr[vid].config.gtx_info);
1131 break;
1132
1133 case WMI_VDEV_PARAM_GTX_USR_CFG:
1134 intr[vid].config.gtx_info.gtxUsrcfg =
1135 privcmd->param_value;
1136 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1137 privcmd->param_vdev_id,
1138 &intr[vid].config.gtx_info);
1139 break;
1140
1141 case WMI_VDEV_PARAM_GTX_THRE:
1142 intr[vid].config.gtx_info.gtxPERThreshold =
1143 privcmd->param_value;
1144 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1145 privcmd->param_vdev_id,
1146 &intr[vid].config.gtx_info);
1147 break;
1148
1149 case WMI_VDEV_PARAM_GTX_MARGIN:
1150 intr[vid].config.gtx_info.gtxPERMargin =
1151 privcmd->param_value;
1152 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1153 privcmd->param_vdev_id,
1154 &intr[vid].config.gtx_info);
1155 break;
1156
1157 case WMI_VDEV_PARAM_GTX_STEP:
1158 intr[vid].config.gtx_info.gtxTPCstep =
1159 privcmd->param_value;
1160 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1161 privcmd->param_vdev_id,
1162 &intr[vid].config.gtx_info);
1163 break;
1164
1165 case WMI_VDEV_PARAM_GTX_MINTPC:
1166 intr[vid].config.gtx_info.gtxTPCMin =
1167 privcmd->param_value;
1168 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1169 privcmd->param_vdev_id,
1170 &intr[vid].config.gtx_info);
1171 break;
1172
1173 case WMI_VDEV_PARAM_GTX_BW_MASK:
1174 intr[vid].config.gtx_info.gtxBWMask =
1175 privcmd->param_value;
1176 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle,
1177 privcmd->param_vdev_id,
1178 &intr[vid].config.gtx_info);
1179 if (ret) {
1180 WMA_LOGE("wmi_unified_vdev_set_param_send"
1181 " failed ret %d", ret);
1182 return;
1183 }
1184 break;
1185 default:
1186 break;
1187 }
1188 break;
1189
1190 default:
1191 WMA_LOGE("Invalid vpdev command id");
1192 }
1193 if (1 == privcmd->param_vp_dev) {
1194 switch (privcmd->param_id) {
1195 case WMI_VDEV_PARAM_NSS:
1196 intr[vid].config.nss = privcmd->param_value;
1197 break;
1198 case WMI_VDEV_PARAM_LDPC:
1199 intr[vid].config.ldpc = privcmd->param_value;
1200 break;
1201 case WMI_VDEV_PARAM_TX_STBC:
1202 intr[vid].config.tx_stbc = privcmd->param_value;
1203 break;
1204 case WMI_VDEV_PARAM_RX_STBC:
1205 intr[vid].config.rx_stbc = privcmd->param_value;
1206 break;
1207 case WMI_VDEV_PARAM_SGI:
1208 intr[vid].config.shortgi = privcmd->param_value;
1209 break;
1210 case WMI_VDEV_PARAM_ENABLE_RTSCTS:
1211 intr[vid].config.rtscts_en = privcmd->param_value;
1212 break;
1213 case WMI_VDEV_PARAM_CHWIDTH:
1214 intr[vid].config.chwidth = privcmd->param_value;
1215 break;
1216 case WMI_VDEV_PARAM_FIXED_RATE:
1217 intr[vid].config.tx_rate = privcmd->param_value;
1218 break;
1219 case WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE:
1220 intr[vid].config.erx_adjust = privcmd->param_value;
1221 break;
1222 case WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM:
1223 intr[vid].config.erx_bmiss_num = privcmd->param_value;
1224 break;
1225 case WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE:
1226 intr[vid].config.erx_bmiss_cycle = privcmd->param_value;
1227 break;
1228 case WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP:
1229 intr[vid].config.erx_slop_step = privcmd->param_value;
1230 break;
1231 case WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP:
1232 intr[vid].config.erx_init_slop = privcmd->param_value;
1233 break;
1234 case WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE:
1235 intr[vid].config.erx_adj_pause = privcmd->param_value;
1236 break;
1237 case WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE:
1238 intr[vid].config.erx_dri_sample = privcmd->param_value;
1239 break;
1240 default:
1241 WMA_LOGE("Invalid wma_cli_set vdev command/Not"
1242 " yet implemented 0x%x", privcmd->param_id);
1243 break;
1244 }
1245 } else if (2 == privcmd->param_vp_dev) {
1246 switch (privcmd->param_id) {
1247 case WMI_PDEV_PARAM_ANI_ENABLE:
1248 wma->pdevconfig.ani_enable = privcmd->param_value;
1249 break;
1250 case WMI_PDEV_PARAM_ANI_POLL_PERIOD:
1251 wma->pdevconfig.ani_poll_len = privcmd->param_value;
1252 break;
1253 case WMI_PDEV_PARAM_ANI_LISTEN_PERIOD:
1254 wma->pdevconfig.ani_listen_len = privcmd->param_value;
1255 break;
1256 case WMI_PDEV_PARAM_ANI_OFDM_LEVEL:
1257 wma->pdevconfig.ani_ofdm_level = privcmd->param_value;
1258 break;
1259 case WMI_PDEV_PARAM_ANI_CCK_LEVEL:
1260 wma->pdevconfig.ani_cck_level = privcmd->param_value;
1261 break;
1262 case WMI_PDEV_PARAM_DYNAMIC_BW:
1263 wma->pdevconfig.cwmenable = privcmd->param_value;
1264 break;
1265 case WMI_PDEV_PARAM_CTS_CBW:
1266 wma->pdevconfig.cts_cbw = privcmd->param_value;
1267 break;
1268 case WMI_PDEV_PARAM_TX_CHAIN_MASK:
1269 wma->pdevconfig.txchainmask = privcmd->param_value;
1270 break;
1271 case WMI_PDEV_PARAM_RX_CHAIN_MASK:
1272 wma->pdevconfig.rxchainmask = privcmd->param_value;
1273 break;
1274 case WMI_PDEV_PARAM_BURST_ENABLE:
1275 wma->pdevconfig.burst_enable = privcmd->param_value;
1276 if ((wma->pdevconfig.burst_enable == 1) &&
1277 (wma->pdevconfig.burst_dur == 0))
1278 wma->pdevconfig.burst_dur =
1279 WMA_DEFAULT_SIFS_BURST_DURATION;
1280 else if (wma->pdevconfig.burst_enable == 0)
1281 wma->pdevconfig.burst_dur = 0;
1282 break;
1283 case WMI_PDEV_PARAM_BURST_DUR:
1284 wma->pdevconfig.burst_dur = privcmd->param_value;
1285 break;
1286 case WMI_PDEV_PARAM_POWER_GATING_SLEEP:
1287 wma->pdevconfig.pwrgating = privcmd->param_value;
1288 break;
1289 case WMI_PDEV_PARAM_TXPOWER_LIMIT2G:
1290 wma->pdevconfig.txpow2g = privcmd->param_value;
1291 if ((pMac->roam.configParam.bandCapability ==
1292 eCSR_BAND_ALL) ||
1293 (pMac->roam.configParam.bandCapability ==
1294 eCSR_BAND_24)) {
1295 if (cfg_set_int(pMac,
1296 WNI_CFG_CURRENT_TX_POWER_LEVEL,
1297 privcmd->param_value) !=
1298 eSIR_SUCCESS)
1299 WMA_LOGE("could not set WNI_CFG_CURRENT_TX_POWER_LEVEL");
1300
1301 } else {
1302 WMA_LOGE("Current band is not 2G");
1303 }
1304 break;
1305 case WMI_PDEV_PARAM_TXPOWER_LIMIT5G:
1306 wma->pdevconfig.txpow5g = privcmd->param_value;
1307 if ((pMac->roam.configParam.bandCapability ==
1308 eCSR_BAND_ALL) ||
1309 (pMac->roam.configParam.bandCapability ==
1310 eCSR_BAND_5G)) {
1311 if (cfg_set_int(pMac,
1312 WNI_CFG_CURRENT_TX_POWER_LEVEL,
1313 privcmd->param_value) !=
1314 eSIR_SUCCESS)
1315 WMA_LOGE("could not set WNI_CFG_CURRENT_TX_POWER_LEVEL");
1316
1317 } else {
1318 WMA_LOGE("Current band is not 5G");
1319 }
1320 break;
1321 default:
1322 WMA_LOGE("Invalid wma_cli_set pdev command/Not yet implemented 0x%x",
1323 privcmd->param_id);
1324 break;
1325 }
1326 } else if (5 == privcmd->param_vp_dev) {
1327 ret = wmi_unified_vdev_set_param_send(wma->wmi_handle,
1328 privcmd->param_vdev_id,
1329 WMI_VDEV_PARAM_PACKET_POWERSAVE,
1330 pps_val);
1331 if (ret)
1332 WMA_LOGE("Failed to send wmi packet power save cmd");
1333 else
1334 WMA_LOGD("Sent packet power save cmd %d value %x to target",
1335 privcmd->param_id, pps_val);
1336 }
1337}
1338
1339/**
1340 * wma_process_fw_event() - process any fw event
1341 * @wma: wma handle
1342 * @buf: fw event buffer
1343 *
1344 * This function process any fw event to serialize it through mc thread.
1345 *
1346 * Return: none
1347 */
1348static int wma_process_fw_event(tp_wma_handle wma,
1349 wma_process_fw_event_params *buf)
1350{
1351 struct wmi_unified *wmi_handle = (struct wmi_unified *)buf->wmi_handle;
1352
1353 wmi_process_fw_event(wmi_handle, buf->evt_buf);
1354 return 0;
1355}
1356
1357/**
1358 * wma_process_fw_event_handler() - common event handler to serialize
1359 * event processing through mc_thread
1360 * @wmi_handle: wmi handle
1361 * @evt_buf: event buffer
1362 *
1363 * Return: 0 on success, errno on failure
1364 */
1365int wma_process_fw_event_handler(struct wmi_unified *wmi_handle,
1366 wmi_buf_t evt_buf)
1367{
1368 wma_process_fw_event_params *params_buf;
1369 cds_msg_t cds_msg = { 0 };
1370
1371 params_buf = cdf_mem_malloc(sizeof(wma_process_fw_event_params));
1372 if (!params_buf) {
1373 WMA_LOGE("%s: Failed alloc memory for params_buf", __func__);
1374 cdf_nbuf_free(evt_buf);
1375 return -ENOMEM;
1376 }
1377
1378 params_buf->wmi_handle = wmi_handle;
1379 params_buf->evt_buf = evt_buf;
1380
1381 cds_msg.type = WMA_PROCESS_FW_EVENT;
1382 cds_msg.bodyptr = params_buf;
1383 cds_msg.bodyval = 0;
1384
1385 if (CDF_STATUS_SUCCESS !=
1386 cds_mq_post_message(CDS_MQ_ID_WMA, &cds_msg)) {
1387 WMA_LOGP("%s: Failed to post WMA_PROCESS_FW_EVENT msg",
1388 __func__);
1389 cdf_nbuf_free(evt_buf);
1390 cdf_mem_free(params_buf);
1391 return -EFAULT;
1392 }
1393 WMA_LOGD("WMA_PROCESS_FW_EVENT posted");
1394 return 0;
1395
1396}
1397
1398#ifdef QCA_LL_TX_FLOW_CONTROL_V2
1399/**
1400 * ol_cfg_set_flow_control_parameters() - set flow control parameters
1401 * @olCfg: cfg parameters
1402 * @mac_params: mac parameters
1403 *
1404 * Return: none
1405 */
1406static
1407void ol_cfg_set_flow_control_parameters(struct txrx_pdev_cfg_param_t *olCfg,
1408 tMacOpenParameters *mac_params)
1409{
1410 olCfg->tx_flow_start_queue_offset =
1411 mac_params->tx_flow_start_queue_offset;
1412 olCfg->tx_flow_stop_queue_th =
1413 mac_params->tx_flow_stop_queue_th;
1414}
1415#else
1416static
1417void ol_cfg_set_flow_control_parameters(struct txrx_pdev_cfg_param_t *olCfg,
1418 tMacOpenParameters *mac_params)
1419{
1420 return;
1421}
1422#endif
1423
1424#ifdef WLAN_FEATURE_NAN
1425/**
1426 * wma_set_nan_enable() - set nan enable flag in WMA handle
1427 * @wma_handle: Pointer to wma handle
1428 * @mac_param: Pointer to mac_param
1429 *
1430 * Return: none
1431 */
1432static void wma_set_nan_enable(tp_wma_handle wma_handle,
1433 tMacOpenParameters *mac_param)
1434{
1435 wma_handle->is_nan_enabled = mac_param->is_nan_enabled;
1436}
1437#else
1438static void wma_set_nan_enable(tp_wma_handle wma_handle,
1439 tMacOpenParameters *mac_param)
1440{
1441}
1442#endif
1443
1444/**
1445 * wma_open() - Allocate wma context and initialize it.
1446 * @cds_context: cds context
1447 * @wma_tgt_cfg_cb: tgt config callback fun
1448 * @radar_ind_cb: dfs radar indication callback
1449 * @mac_params: mac parameters
1450 *
1451 * Return: 0 on success, errno on failure
1452 */
1453CDF_STATUS wma_open(void *cds_context,
1454 wma_tgt_cfg_cb tgt_cfg_cb,
1455 wma_dfs_radar_indication_cb radar_ind_cb,
1456 tMacOpenParameters *mac_params)
1457{
1458 tp_wma_handle wma_handle;
1459 HTC_HANDLE htc_handle;
1460 cdf_device_t cdf_dev;
1461 void *wmi_handle;
1462 CDF_STATUS cdf_status;
1463 struct ol_softc *scn;
1464 struct txrx_pdev_cfg_param_t olCfg = { 0 };
1465
1466 WMA_LOGD("%s: Enter", __func__);
1467
1468 cdf_dev = cds_get_context(CDF_MODULE_ID_CDF_DEVICE);
1469 htc_handle = cds_get_context(CDF_MODULE_ID_HTC);
1470
1471 if (!htc_handle) {
1472 WMA_LOGP("%s: Invalid HTC handle", __func__);
1473 return CDF_STATUS_E_INVAL;
1474 }
1475
1476 /* Alloc memory for WMA Context */
1477 cdf_status = cds_alloc_context(cds_context, CDF_MODULE_ID_WMA,
1478 (void **)&wma_handle,
1479 sizeof(t_wma_handle));
1480
1481 if (cdf_status != CDF_STATUS_SUCCESS) {
1482 WMA_LOGP("%s: Memory allocation failed for wma_handle",
1483 __func__);
1484 return cdf_status;
1485 }
1486
1487 cdf_mem_zero(wma_handle, sizeof(t_wma_handle));
1488
1489 if (cds_get_conparam() != CDF_FTM_MODE) {
1490#ifdef FEATURE_WLAN_SCAN_PNO
1491 cdf_wake_lock_init(&wma_handle->pno_wake_lock, "wlan_pno_wl");
1492#endif /* FEATURE_WLAN_SCAN_PNO */
1493#ifdef FEATURE_WLAN_EXTSCAN
1494 cdf_wake_lock_init(&wma_handle->extscan_wake_lock,
1495 "wlan_extscan_wl");
1496#endif /* FEATURE_WLAN_EXTSCAN */
1497 cdf_wake_lock_init(&wma_handle->wow_wake_lock, "wlan_wow_wl");
1498 }
1499
1500 /* attach the wmi */
1501 wmi_handle = wmi_unified_attach(wma_handle,
1502 wma_process_fw_event_handler);
1503 if (!wmi_handle) {
1504 WMA_LOGP("%s: failed to attach WMI", __func__);
1505 cdf_status = CDF_STATUS_E_NOMEM;
1506 goto err_wma_handle;
1507 }
1508
1509 WMA_LOGA("WMA --> wmi_unified_attach - success");
1510
1511 /* Save the WMI & HTC handle */
1512 wma_handle->wmi_handle = wmi_handle;
1513 wma_handle->htc_handle = htc_handle;
1514 wma_handle->cds_context = cds_context;
1515 wma_handle->cdf_dev = cdf_dev;
1516 wma_handle->max_scan = mac_params->max_scan;
1517
1518 /* initialize default target config */
1519 wma_set_default_tgt_config(wma_handle);
1520
1521 olCfg.is_uc_offload_enabled = mac_params->ucOffloadEnabled;
1522 olCfg.uc_tx_buffer_count = mac_params->ucTxBufCount;
1523 olCfg.uc_tx_buffer_size = mac_params->ucTxBufSize;
1524 olCfg.uc_rx_indication_ring_count = mac_params->ucRxIndRingCount;
1525 olCfg.uc_tx_partition_base = mac_params->ucTxPartitionBase;
1526
1527
1528 wma_handle->tx_chain_mask_cck = mac_params->tx_chain_mask_cck;
1529 wma_handle->self_gen_frm_pwr = mac_params->self_gen_frm_pwr;
1530
1531 /* Allocate cfg handle */
1532
1533 /* RX Full reorder should enable for PCIe, ROME3.X project only now
1534 * MDM should enable later, schedule TBD
1535 * HL also sdould be enabled, schedule TBD
1536 */
1537#ifdef WLAN_FEATURE_RX_FULL_REORDER_OL
1538 olCfg.is_full_reorder_offload = mac_params->reorderOffload;
1539#else
1540 olCfg.is_full_reorder_offload = 0;
1541#endif /* WLAN_FEATURE_RX_FULL_REORDER_OL */
1542 olCfg.enable_rxthread = mac_params->enable_rxthread;
1543 olCfg.ip_tcp_udp_checksum_offload =
1544 mac_params->ip_tcp_udp_checksum_offload;
1545 olCfg.ce_classify_enabled = mac_params->ce_classify_enabled;
1546
1547 ol_cfg_set_flow_control_parameters(&olCfg, mac_params);
1548
1549 ((p_cds_contextType) cds_context)->cfg_ctx =
1550 ol_pdev_cfg_attach(((p_cds_contextType) cds_context)->cdf_ctx,
1551 olCfg);
1552 if (!(((p_cds_contextType) cds_context)->cfg_ctx)) {
1553 WMA_LOGP("%s: failed to init cfg handle", __func__);
1554 cdf_status = CDF_STATUS_E_NOMEM;
1555 goto err_wmi_handle;
1556 }
1557
1558 /* adjust the cfg_ctx default value based on setting */
1559 ol_set_cfg_rx_fwd_disabled((ol_pdev_handle)
1560 ((p_cds_contextType) cds_context)->cfg_ctx,
1561 (uint8_t) mac_params->apDisableIntraBssFwd);
1562
1563 /* adjust the packet log enable default value based on CFG INI setting */
1564 ol_set_cfg_packet_log_enabled((ol_pdev_handle)
1565 ((p_cds_contextType) cds_context)->
1566 cfg_ctx,
1567 (uint8_t)cds_is_packet_log_enabled());
1568
1569 /* Allocate dfs_ic and initialize DFS */
1570 wma_handle->dfs_ic = wma_dfs_attach(wma_handle->dfs_ic);
1571 if (wma_handle->dfs_ic == NULL) {
1572 WMA_LOGE("%s: Memory allocation failed for dfs_ic", __func__);
1573 goto err_wmi_handle;
1574 }
1575#if defined(QCA_WIFI_FTM)
1576 if (cds_get_conparam() == CDF_FTM_MODE)
1577 wma_utf_attach(wma_handle);
1578#endif /* QCA_WIFI_FTM */
1579
1580 /*TODO: Recheck below parameters */
1581 scn = cds_get_context(CDF_MODULE_ID_HIF);
1582
1583 if (NULL == scn) {
1584 WMA_LOGE("%s: Failed to get scn", __func__);
1585 cdf_status = CDF_STATUS_E_NOMEM;
1586 goto err_scn_context;
1587 }
1588
1589 mac_params->maxStation = ol_get_number_of_peers_supported(scn);
1590
1591 mac_params->maxBssId = WMA_MAX_SUPPORTED_BSS;
1592 mac_params->frameTransRequired = 0;
1593
1594 wma_handle->wlan_resource_config.num_wow_filters =
1595 mac_params->maxWoWFilters;
1596 wma_handle->wlan_resource_config.num_keep_alive_pattern =
1597 WMA_MAXNUM_PERIODIC_TX_PTRNS;
1598
1599 /* The current firmware implementation requires the number of
1600 * offload peers should be (number of vdevs + 1).
1601 */
1602 wma_handle->wlan_resource_config.num_offload_peers =
1603 mac_params->apMaxOffloadPeers + 1;
1604
1605 wma_handle->wlan_resource_config.num_offload_reorder_buffs =
1606 mac_params->apMaxOffloadReorderBuffs + 1;
1607
1608 wma_handle->ol_ini_info = mac_params->olIniInfo;
1609 wma_handle->max_station = mac_params->maxStation;
1610 wma_handle->max_bssid = mac_params->maxBssId;
1611 wma_handle->frame_xln_reqd = mac_params->frameTransRequired;
1612 wma_handle->driver_type = mac_params->driverType;
1613 wma_handle->ssdp = mac_params->ssdp;
1614#ifdef FEATURE_WLAN_RA_FILTERING
1615 wma_handle->IsRArateLimitEnabled = mac_params->IsRArateLimitEnabled;
1616 wma_handle->RArateLimitInterval = mac_params->RArateLimitInterval;
1617#endif /* FEATURE_WLAN_RA_FILTERING */
1618#ifdef WLAN_FEATURE_LPSS
1619 wma_handle->is_lpass_enabled = mac_params->is_lpass_enabled;
1620#endif
1621 wma_set_nan_enable(wma_handle, mac_params);
1622 /*
1623 * Indicates if DFS Phyerr filtering offload
1624 * is Enabled/Disabed from ini
1625 */
1626 wma_handle->dfs_phyerr_filter_offload =
1627 mac_params->dfsPhyerrFilterOffload;
1628 wma_handle->dfs_pri_multiplier = mac_params->dfsRadarPriMultiplier;
1629 wma_handle->interfaces = cdf_mem_malloc(sizeof(struct wma_txrx_node) *
1630 wma_handle->max_bssid);
1631 if (!wma_handle->interfaces) {
1632 WMA_LOGP("%s: failed to allocate interface table", __func__);
1633 cdf_status = CDF_STATUS_E_NOMEM;
1634 goto err_scn_context;
1635 }
1636 cdf_mem_zero(wma_handle->interfaces, sizeof(struct wma_txrx_node) *
1637 wma_handle->max_bssid);
1638 /* Register the debug print event handler */
1639 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1640 WMI_DEBUG_PRINT_EVENTID,
1641 wma_unified_debug_print_event_handler);
1642
1643 wma_handle->tgt_cfg_update_cb = tgt_cfg_cb;
1644 wma_handle->dfs_radar_indication_cb = radar_ind_cb;
1645 wma_handle->old_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
1646 wma_handle->new_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
1647 wma_handle->saved_wmi_init_cmd.buf = NULL;
1648
1649 cdf_status = cdf_event_init(&wma_handle->wma_ready_event);
1650 if (cdf_status != CDF_STATUS_SUCCESS) {
1651 WMA_LOGP("%s: wma_ready_event initialization failed", __func__);
1652 goto err_event_init;
1653 }
1654 cdf_status = cdf_event_init(&wma_handle->target_suspend);
1655 if (cdf_status != CDF_STATUS_SUCCESS) {
1656 WMA_LOGP("%s: target suspend event initialization failed",
1657 __func__);
1658 goto err_event_init;
1659 }
1660
1661 /* Init Tx Frame Complete event */
1662 cdf_status = cdf_event_init(&wma_handle->tx_frm_download_comp_event);
1663 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1664 WMA_LOGP("%s: failed to init tx_frm_download_comp_event",
1665 __func__);
1666 goto err_event_init;
1667 }
1668
1669 /* Init tx queue empty check event */
1670 cdf_status = cdf_event_init(&wma_handle->tx_queue_empty_event);
1671 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1672 WMA_LOGP("%s: failed to init tx_queue_empty_event", __func__);
1673 goto err_event_init;
1674 }
1675
1676 cdf_status = cdf_event_init(&wma_handle->wma_resume_event);
1677 if (cdf_status != CDF_STATUS_SUCCESS) {
1678 WMA_LOGP("%s: wma_resume_event initialization failed",
1679 __func__);
1680 goto err_event_init;
1681 }
1682
1683 cdf_status = cdf_event_init(&wma_handle->recovery_event);
1684 if (cdf_status != CDF_STATUS_SUCCESS) {
1685 WMA_LOGP("%s: recovery event initialization failed", __func__);
1686 goto err_event_init;
1687 }
1688
1689 INIT_LIST_HEAD(&wma_handle->vdev_resp_queue);
1690 cdf_spinlock_init(&wma_handle->vdev_respq_lock);
1691 cdf_list_init(&wma_handle->wma_hold_req_queue,
1692 MAX_ENTRY_HOLD_REQ_QUEUE);
1693 cdf_spinlock_init(&wma_handle->wma_hold_req_q_lock);
1694 cdf_atomic_init(&wma_handle->is_wow_bus_suspended);
1695 cdf_atomic_init(&wma_handle->scan_id_counter);
1696
1697 /* Register vdev start response event handler */
1698 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1699 WMI_VDEV_START_RESP_EVENTID,
1700 wma_vdev_start_resp_handler);
1701
1702 /* Register vdev stop response event handler */
1703 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1704 WMI_VDEV_STOPPED_EVENTID,
1705 wma_vdev_stop_resp_handler);
1706
1707 /* register for STA kickout function */
1708 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1709 WMI_PEER_STA_KICKOUT_EVENTID,
1710 wma_peer_sta_kickout_event_handler);
1711
1712 /* register for stats response event */
1713 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1714 WMI_UPDATE_STATS_EVENTID,
1715 wma_stats_event_handler);
1716 /* register for linkspeed response event */
1717 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1718 WMI_PEER_ESTIMATED_LINKSPEED_EVENTID,
1719 wma_link_speed_event_handler);
1720
1721#ifdef FEATURE_OEM_DATA_SUPPORT
1722 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1723 WMI_OEM_CAPABILITY_EVENTID,
1724 wma_oem_capability_event_callback);
1725
1726 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1727 WMI_OEM_MEASUREMENT_REPORT_EVENTID,
1728 wma_oem_measurement_report_event_callback);
1729
1730 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1731 WMI_OEM_ERROR_REPORT_EVENTID,
1732 wma_oem_error_report_event_callback);
1733#endif /* FEATURE_OEM_DATA_SUPPORT */
1734 /*
1735 * Register appropriate DFS phyerr event handler for
1736 * Phyerror events. Handlers differ for phyerr filtering
1737 * offload enable and disable cases.
1738 */
1739 wma_register_dfs_event_handler(wma_handle);
1740
1741 /* Register peer change event handler */
1742 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1743 WMI_PEER_STATE_EVENTID,
1744 wma_peer_state_change_event_handler);
1745
1746 /* Register beacon tx complete event id. The event is required
1747 * for sending channel switch announcement frames
1748 */
1749 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1750 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID,
1751 wma_unified_bcntx_status_event_handler);
1752
1753 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1754 WMI_UPDATE_VDEV_RATE_STATS_EVENTID,
1755 wma_link_status_event_handler);
1756#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1757 /* Register event handler for processing Link Layer Stats
1758 * response from the FW
1759 */
1760 wma_register_ll_stats_event_handler(wma_handle);
1761
1762#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1763
1764 /*
1765 * Register event handler to receive firmware mem dump
1766 * copy complete indication
1767 */
1768 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1769 WMI_UPDATE_FW_MEM_DUMP_EVENTID,
1770 wma_fw_mem_dump_event_handler);
1771
1772 /* Firmware debug log */
1773 cdf_status = dbglog_init(wma_handle->wmi_handle);
1774 if (cdf_status != CDF_STATUS_SUCCESS) {
1775 WMA_LOGP("%s: Firmware Dbglog initialization failed", __func__);
1776 goto err_dbglog_init;
1777 }
1778
1779 /*
1780 * Update Powersave mode
1781 * 1 - Legacy Powersave + Deepsleep Disabled
1782 * 2 - QPower + Deepsleep Disabled
1783 * 3 - Legacy Powersave + Deepsleep Enabled
1784 * 4 - QPower + Deepsleep Enabled
1785 */
1786 wma_handle->powersave_mode = mac_params->powersaveOffloadEnabled;
1787 wma_handle->staMaxLIModDtim = mac_params->staMaxLIModDtim;
1788 wma_handle->staModDtim = mac_params->staModDtim;
1789 wma_handle->staDynamicDtim = mac_params->staDynamicDtim;
1790
1791 /*
1792 * Value of mac_params->wowEnable can be,
1793 * 0 - Disable both magic pattern match and pattern byte match.
1794 * 1 - Enable magic pattern match on all interfaces.
1795 * 2 - Enable pattern byte match on all interfaces.
1796 * 3 - Enable both magic patter and pattern byte match on
1797 * all interfaces.
1798 */
1799 wma_handle->wow.magic_ptrn_enable =
1800 (mac_params->wowEnable & 0x01) ? true : false;
1801 wma_handle->ptrn_match_enable_all_vdev =
1802 (mac_params->wowEnable & 0x02) ? true : false;
1803
1804#ifdef FEATURE_WLAN_TDLS
1805 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1806 WMI_TDLS_PEER_EVENTID,
1807 wma_tdls_event_handler);
1808#endif /* FEATURE_WLAN_TDLS */
1809
1810 /* register for install key completion event */
1811 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1812 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID,
1813 wma_vdev_install_key_complete_event_handler);
1814#ifdef WLAN_FEATURE_NAN
1815 /* register for nan response event */
1816 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1817 WMI_NAN_EVENTID,
1818 wma_nan_rsp_event_handler);
1819#endif /* WLAN_FEATURE_NAN */
1820
1821#ifdef WLAN_FEATURE_STATS_EXT
1822 /* register for extended stats event */
1823 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1824 WMI_STATS_EXT_EVENTID,
1825 wma_stats_ext_event_handler);
1826#endif /* WLAN_FEATURE_STATS_EXT */
1827#ifdef FEATURE_WLAN_EXTSCAN
1828 wma_register_extscan_event_handler(wma_handle);
1829#endif /* WLAN_FEATURE_STATS_EXT */
1830
1831 WMA_LOGD("%s: Exit", __func__);
1832
1833#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1834 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1835 WMI_ROAM_SYNCH_EVENTID,
1836 wma_roam_synch_event_handler);
1837#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
1838 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1839 WMI_RSSI_BREACH_EVENTID,
1840 wma_rssi_breached_event_handler);
1841
1842 /* Register peer assoc conf event handler */
1843 wmi_unified_register_event_handler(wma_handle->wmi_handle,
1844 WMI_PEER_ASSOC_CONF_EVENTID,
1845 wma_peer_assoc_conf_handler);
1846
1847 return CDF_STATUS_SUCCESS;
1848
1849err_dbglog_init:
1850 cdf_spinlock_destroy(&wma_handle->vdev_respq_lock);
1851 cdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock);
1852err_event_init:
1853 wmi_unified_unregister_event_handler(wma_handle->wmi_handle,
1854 WMI_DEBUG_PRINT_EVENTID);
1855 cdf_mem_free(wma_handle->interfaces);
1856err_scn_context:
1857 wma_dfs_detach(wma_handle->dfs_ic);
1858#if defined(QCA_WIFI_FTM)
1859 wma_utf_detach(wma_handle);
1860#endif /* QCA_WIFI_FTM */
1861err_wmi_handle:
1862 cdf_mem_free(((p_cds_contextType) cds_context)->cfg_ctx);
1863 OS_FREE(wmi_handle);
1864
1865err_wma_handle:
1866
1867 if (cds_get_conparam() != CDF_FTM_MODE) {
1868#ifdef FEATURE_WLAN_SCAN_PNO
1869 cdf_wake_lock_destroy(&wma_handle->pno_wake_lock);
1870#endif /* FEATURE_WLAN_SCAN_PNO */
1871#ifdef FEATURE_WLAN_EXTSCAN
1872 cdf_wake_lock_destroy(&wma_handle->extscan_wake_lock);
1873#endif /* FEATURE_WLAN_EXTSCAN */
1874 cdf_wake_lock_destroy(&wma_handle->wow_wake_lock);
1875 }
1876 cds_free_context(cds_context, CDF_MODULE_ID_WMA, wma_handle);
1877
1878 WMA_LOGD("%s: Exit", __func__);
1879
1880 return cdf_status;
1881}
1882
1883/**
1884 * wma_pre_start() - wma pre start
1885 * @cds_ctx: cds context
1886 *
1887 * Return: 0 on success, errno on failure
1888 */
1889CDF_STATUS wma_pre_start(void *cds_ctx)
1890{
1891 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
1892 A_STATUS status = A_OK;
1893 tp_wma_handle wma_handle;
1894 cds_msg_t wma_msg = { 0 };
1895
1896 WMA_LOGD("%s: Enter", __func__);
1897
1898 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
1899
1900 /* Validate the wma_handle */
1901 if (NULL == wma_handle) {
1902 WMA_LOGP("%s: invalid argument", __func__);
1903 cdf_status = CDF_STATUS_E_INVAL;
1904 goto end;
1905 }
1906 /* Open endpoint for ctrl path - WMI <--> HTC */
1907 status = wmi_unified_connect_htc_service(wma_handle->wmi_handle,
1908 wma_handle->htc_handle);
1909 if (A_OK != status) {
1910 WMA_LOGP("%s: wmi_unified_connect_htc_service", __func__);
1911 cdf_status = CDF_STATUS_E_FAULT;
1912 goto end;
1913 }
1914
1915 WMA_LOGA("WMA --> wmi_unified_connect_htc_service - success");
1916
1917 /* Trigger the CFG DOWNLOAD */
1918 wma_msg.type = WNI_CFG_DNLD_REQ;
1919 wma_msg.bodyptr = NULL;
1920 wma_msg.bodyval = 0;
1921
1922 cdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &wma_msg);
1923 if (CDF_STATUS_SUCCESS != cdf_status) {
1924 WMA_LOGP("%s: Failed to post WNI_CFG_DNLD_REQ msg", __func__);
1925 CDF_ASSERT(0);
1926 cdf_status = CDF_STATUS_E_FAILURE;
1927 }
1928end:
1929 WMA_LOGD("%s: Exit", __func__);
1930 return cdf_status;
1931}
1932
1933/**
1934 * wma_send_msg() - Send wma message to PE.
1935 * @wma_handle: wma handle
1936 * @msg_type: message type
1937 * @body_ptr: message body ptr
1938 * @body_val: message body value
1939 *
1940 * Return: none
1941 */
1942void wma_send_msg(tp_wma_handle wma_handle, uint16_t msg_type,
1943 void *body_ptr, uint32_t body_val)
1944{
1945 tSirMsgQ msg = { 0 };
1946 uint32_t status = CDF_STATUS_SUCCESS;
1947 tpAniSirGlobal pMac = cds_get_context(CDF_MODULE_ID_PE);
1948 msg.type = msg_type;
1949 msg.bodyval = body_val;
1950 msg.bodyptr = body_ptr;
1951 status = lim_post_msg_api(pMac, &msg);
1952 if (CDF_STATUS_SUCCESS != status) {
1953 if (NULL != body_ptr)
1954 cdf_mem_free(body_ptr);
1955 CDF_ASSERT(0);
1956 }
1957 return;
1958}
1959
1960/**
1961 * wma_set_base_macaddr_indicate() - set base mac address in fw
1962 * @wma_handle: wma handle
1963 * @customAddr: base mac address
1964 *
1965 * Return: 0 for success or error code
1966 */
1967static int wma_set_base_macaddr_indicate(tp_wma_handle wma_handle,
1968 tSirMacAddr *customAddr)
1969{
1970 wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
1971 wmi_buf_t buf;
1972 int err;
1973
1974 buf = wmi_buf_alloc(wma_handle->wmi_handle, sizeof(*cmd));
1975 if (!buf) {
1976 WMA_LOGE("Failed to allocate buffer to send set_base_macaddr cmd");
1977 return -ENOMEM;
1978 }
1979
1980 cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
1981 cdf_mem_zero(cmd, sizeof(*cmd));
1982
1983 WMITLV_SET_HDR(&cmd->tlv_header,
1984 WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
1985 WMITLV_GET_STRUCT_TLVLEN
1986 (wmi_pdev_set_base_macaddr_cmd_fixed_param));
1987 WMI_CHAR_ARRAY_TO_MAC_ADDR(*customAddr, &cmd->base_macaddr);
1988 err = wmi_unified_cmd_send(wma_handle->wmi_handle, buf,
1989 sizeof(*cmd),
1990 WMI_PDEV_SET_BASE_MACADDR_CMDID);
1991 if (err) {
1992 WMA_LOGE("Failed to send set_base_macaddr cmd");
1993 cdf_mem_free(buf);
1994 return -EIO;
1995 }
1996 WMA_LOGD("Base MAC Addr: " MAC_ADDRESS_STR,
1997 MAC_ADDR_ARRAY((*customAddr)));
1998
1999 return 0;
2000}
2001
2002/**
2003 * wma_log_supported_evt_handler() - Enable/Disable FW diag/log events
2004 * @handle: WMA handle
2005 * @event: Event received from FW
2006 * @len: Length of the event
2007 *
2008 * Enables the low frequency events and disables the high frequency
2009 * events. Bit 17 indicates if the event if low/high frequency.
2010 * 1 - high frequency, 0 - low frequency
2011 *
2012 * Return: 0 on successfully enabling/disabling the events
2013 */
2014static int wma_log_supported_evt_handler(void *handle,
2015 uint8_t *event,
2016 uint32_t len)
2017{
2018 tp_wma_handle wma = (tp_wma_handle) handle;
2019 uint32_t num_of_diag_events_logs;
2020 wmi_diag_event_log_config_fixed_param *cmd;
2021 wmi_buf_t buf;
2022 uint8_t *buf_ptr;
2023 uint32_t *cmd_args, *evt_args;
2024 uint32_t buf_len, i;
2025
2026 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *param_buf;
2027 wmi_diag_event_log_supported_event_fixed_params *wmi_event;
2028
2029 WMA_LOGI("Received WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID");
2030
2031 param_buf = (WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID_param_tlvs *) event;
2032 if (!param_buf) {
2033 WMA_LOGE("Invalid log supported event buffer");
2034 return -EINVAL;
2035 }
2036 wmi_event = param_buf->fixed_param;
2037 num_of_diag_events_logs = wmi_event->num_of_diag_events_logs;
2038 evt_args = param_buf->diag_events_logs_list;
2039 if (!evt_args) {
2040 WMA_LOGE("%s: Event list is empty, num_of_diag_events_logs=%d",
2041 __func__, num_of_diag_events_logs);
2042 return -EINVAL;
2043 }
2044
2045 WMA_LOGD("%s: num_of_diag_events_logs=%d",
2046 __func__, num_of_diag_events_logs);
2047
2048 /* Free any previous allocation */
2049 if (wma->events_logs_list)
2050 cdf_mem_free(wma->events_logs_list);
2051
2052 /* Store the event list for run time enable/disable */
2053 wma->events_logs_list = cdf_mem_malloc(num_of_diag_events_logs *
2054 sizeof(uint32_t));
2055 if (!wma->events_logs_list) {
2056 WMA_LOGE("%s: event log list memory allocation failed",
2057 __func__);
2058 return -ENOMEM;
2059 }
2060 wma->num_of_diag_events_logs = num_of_diag_events_logs;
2061
2062 /* Prepare the send buffer */
2063 buf_len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
2064 (num_of_diag_events_logs * sizeof(uint32_t));
2065
2066 buf = wmi_buf_alloc(wma->wmi_handle, buf_len);
2067 if (!buf) {
2068 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
2069 cdf_mem_free(wma->events_logs_list);
2070 wma->events_logs_list = NULL;
2071 return -ENOMEM;
2072 }
2073
2074 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
2075 buf_ptr = (uint8_t *) cmd;
2076
2077 WMITLV_SET_HDR(&cmd->tlv_header,
2078 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
2079 WMITLV_GET_STRUCT_TLVLEN(
2080 wmi_diag_event_log_config_fixed_param));
2081
2082 cmd->num_of_diag_events_logs = num_of_diag_events_logs;
2083
2084 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
2085
2086 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
2087 (num_of_diag_events_logs * sizeof(uint32_t)));
2088
2089 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
2090
2091 /* Populate the events */
2092 for (i = 0; i < num_of_diag_events_logs; i++) {
2093 /* Low freq (0) - Enable (1) the event
2094 * High freq (1) - Disable (0) the event
2095 */
2096 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[i],
2097 !(WMI_DIAG_FREQUENCY_GET(evt_args[i])));
2098 /* Set the event ID */
2099 WMI_DIAG_ID_SET(cmd_args[i],
2100 WMI_DIAG_ID_GET(evt_args[i]));
2101 /* Set the type */
2102 WMI_DIAG_TYPE_SET(cmd_args[i],
2103 WMI_DIAG_TYPE_GET(evt_args[i]));
2104 /* Storing the event/log list in WMA */
2105 wma->events_logs_list[i] = evt_args[i];
2106 }
2107
2108 if (wmi_unified_cmd_send(wma->wmi_handle, buf, buf_len,
2109 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
2110 WMA_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
2111 __func__);
2112 wmi_buf_free(buf);
2113 /* Not clearing events_logs_list, though wmi cmd failed.
2114 * Host can still have this list
2115 */
2116 return -EINVAL;
2117 }
2118
2119 return 0;
2120}
2121
2122/**
2123 * wma_flush_complete_evt_handler() - FW log flush complete event handler
2124 * @handle: WMI handle
2125 * @event: Event recevied from FW
2126 * @len: Length of the event
2127 *
2128 */
2129static int wma_flush_complete_evt_handler(void *handle,
2130 u_int8_t *event,
2131 u_int32_t len)
2132{
2133 CDF_STATUS status;
2134 tp_wma_handle wma = (tp_wma_handle) handle;
2135
2136 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID_param_tlvs *param_buf;
2137 wmi_debug_mesg_flush_complete_fixed_param *wmi_event;
2138 uint32_t reason_code;
2139
2140 param_buf = (WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID_param_tlvs *) event;
2141 if (!param_buf) {
2142 WMA_LOGE("Invalid log flush complete event buffer");
2143 return CDF_STATUS_E_FAILURE;
2144 }
2145
2146 wmi_event = param_buf->fixed_param;
2147 reason_code = wmi_event->reserved0;
2148
2149 /*
2150 * reason_code = 0; Flush event in response to flush command
2151 * reason_code = other value; Asynchronous flush event for fatal events
2152 */
2153 if (!reason_code && (cds_is_log_report_in_progress() == false)) {
2154 WMA_LOGE("Received WMI flush event without sending CMD");
2155 return -EINVAL;
2156 } else if (!reason_code && cds_is_log_report_in_progress() == true) {
2157 /* Flush event in response to flush command */
2158 WMA_LOGI("Received WMI flush event in response to flush CMD");
2159 status = cdf_mc_timer_stop(&wma->log_completion_timer);
2160 if (status != CDF_STATUS_SUCCESS)
2161 WMA_LOGE("Failed to stop the log completion timeout");
2162 cds_logging_set_fw_flush_complete();
2163 } else if (reason_code && cds_is_log_report_in_progress() == false) {
2164 /* Asynchronous flush event for fatal events */
2165 WMA_LOGE("Received asynchronous WMI flush event: reason=%d",
2166 reason_code);
2167 status = cds_set_log_completion(WLAN_LOG_TYPE_FATAL,
2168 WLAN_LOG_INDICATOR_FIRMWARE,
2169 reason_code);
2170 if (CDF_STATUS_SUCCESS != status) {
2171 WMA_LOGE("%s: Failed to set log trigger params",
2172 __func__);
2173 return CDF_STATUS_E_FAILURE;
2174 }
2175 cds_logging_set_fw_flush_complete();
2176 return status;
2177 } else {
2178 /* Asynchronous flush event for fatal event,
2179 * but, report in progress already
2180 */
2181 WMA_LOGI("%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
2182 __func__, WLAN_LOG_TYPE_FATAL,
2183 WLAN_LOG_INDICATOR_FIRMWARE, reason_code);
2184 return CDF_STATUS_E_FAILURE;
2185 }
2186 return 0;
2187}
2188
2189/**
2190 * wma_soc_set_hw_mode_resp_evt_handler() - Set HW mode resp evt handler
2191 * @handle: WMI handle
2192 * @event: Event recevied from FW
2193 * @len: Length of the event
2194 *
2195 * Event handler for WMI_SOC_SET_HW_MODE_RESP_EVENTID that is sent to host
2196 * driver in response to a WMI_SOC_SET_HW_MODE_CMDID being sent to WLAN firmware
2197 *
2198 * Return: Success on receiving valid params from FW
2199 */
2200static int wma_soc_set_hw_mode_resp_evt_handler(void *handle,
2201 uint8_t *event,
2202 uint32_t len)
2203{
2204 WMI_SOC_SET_HW_MODE_RESP_EVENTID_param_tlvs *param_buf;
2205 wmi_soc_set_hw_mode_response_event_fixed_param *wmi_event;
2206 wmi_soc_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
2207 uint32_t i;
2208 struct sir_set_hw_mode_resp *hw_mode_resp;
2209 tp_wma_handle wma = (tp_wma_handle) handle;
2210
2211 if (!wma) {
2212 WMA_LOGE("%s: Invalid WMA handle", __func__);
2213 /* Since WMA handle itself is NULL, we cannot send fail
2214 * response back to LIM here
2215 */
2216 return CDF_STATUS_E_NULL_VALUE;
2217 }
2218
2219 hw_mode_resp = cdf_mem_malloc(sizeof(*hw_mode_resp));
2220 if (!hw_mode_resp) {
2221 WMA_LOGI("%s: Memory allocation failed", __func__);
2222 /* Since this memory allocation itself failed, we cannot
2223 * send fail response back to LIM here
2224 */
2225 return CDF_STATUS_E_NULL_VALUE;
2226 }
2227
2228 param_buf = (WMI_SOC_SET_HW_MODE_RESP_EVENTID_param_tlvs *) event;
2229 if (!param_buf) {
2230 WMA_LOGE("Invalid WMI_SOC_SET_HW_MODE_RESP_EVENTID event");
2231 /* Need to send response back to upper layer to free
2232 * active command list
2233 */
2234 goto fail;
2235 }
2236
2237 wmi_event = param_buf->fixed_param;
2238 hw_mode_resp->status = wmi_event->status;
2239 hw_mode_resp->cfgd_hw_mode_index = wmi_event->cfgd_hw_mode_index;
2240 hw_mode_resp->num_vdev_mac_entries = wmi_event->num_vdev_mac_entries;
2241
2242 WMA_LOGI("%s: status:%d cfgd_hw_mode_index:%d num_vdev_mac_entries:%d",
2243 __func__, wmi_event->status,
2244 wmi_event->cfgd_hw_mode_index,
2245 wmi_event->num_vdev_mac_entries);
2246 vdev_mac_entry =
2247 param_buf->wmi_soc_set_hw_mode_response_vdev_mac_mapping;
2248
2249 /* Store the vdev-mac map in WMA and prepare to send to PE */
2250 for (i = 0; i < wmi_event->num_vdev_mac_entries; i++) {
2251 uint32_t vdev_id, mac_id;
2252 vdev_id = vdev_mac_entry[i].vdev_id;
2253 mac_id = vdev_mac_entry[i].mac_id;
2254
2255 WMA_LOGI("%s: vdev_id:%d mac_id:%d",
2256 __func__, vdev_id, mac_id);
2257
2258 hw_mode_resp->vdev_mac_map[i].vdev_id = vdev_id;
2259 hw_mode_resp->vdev_mac_map[i].mac_id = mac_id;
2260 wma_update_intf_hw_mode_params(vdev_id, mac_id,
2261 wmi_event->cfgd_hw_mode_index);
2262 }
2263
2264 if (hw_mode_resp->status == SET_HW_MODE_STATUS_OK) {
2265 if (WMA_DEFAULT_HW_MODE_INDEX == wma->new_hw_mode_index) {
2266 wma->new_hw_mode_index = wmi_event->cfgd_hw_mode_index;
2267 } else {
2268 wma->old_hw_mode_index = wma->new_hw_mode_index;
2269 wma->new_hw_mode_index = wmi_event->cfgd_hw_mode_index;
2270 }
2271 }
2272
2273 WMA_LOGI("%s: Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
2274 __func__, wma->old_hw_mode_index, wma->new_hw_mode_index);
2275
2276 wma_send_msg(wma, SIR_HAL_SOC_SET_HW_MODE_RESP,
2277 (void *) hw_mode_resp, 0);
2278
2279 return CDF_STATUS_SUCCESS;
2280
2281fail:
2282 WMA_LOGE("%s: Sending fail response to LIM", __func__);
2283 hw_mode_resp->status = SET_HW_MODE_STATUS_ECANCELED;
2284 hw_mode_resp->cfgd_hw_mode_index = 0;
2285 hw_mode_resp->num_vdev_mac_entries = 0;
2286 wma_send_msg(wma, SIR_HAL_SOC_SET_HW_MODE_RESP,
2287 (void *) hw_mode_resp, 0);
2288
2289 return CDF_STATUS_E_FAILURE;
2290}
2291
2292/**
2293 * wma_soc_hw_mode_transition_evt_handler() - HW mode transition evt handler
2294 * @handle: WMI handle
2295 * @event: Event recevied from FW
2296 * @len: Length of the event
2297 *
2298 * Event handler for WMI_SOC_HW_MODE_TRANSITION_EVENTID that indicates an
2299 * asynchronous hardware mode transition. This event notifies the host driver
2300 * that firmware independently changed the hardware mode for some reason, such
2301 * as Coex, LFR 3.0, etc
2302 *
2303 * Return: Success on receiving valid params from FW
2304 */
2305static int wma_soc_hw_mode_transition_evt_handler(void *handle,
2306 uint8_t *event,
2307 uint32_t len)
2308{
2309 uint32_t i;
2310 WMI_SOC_HW_MODE_TRANSITION_EVENTID_param_tlvs *param_buf;
2311 wmi_soc_hw_mode_transition_event_fixed_param *wmi_event;
2312 wmi_soc_set_hw_mode_response_vdev_mac_entry *vdev_mac_entry;
2313 struct sir_hw_mode_trans_ind *hw_mode_trans_ind;
2314 tp_wma_handle wma = (tp_wma_handle) handle;
2315
2316 if (!wma) {
2317 /* This is an async event. So, not sending any event to LIM */
2318 WMA_LOGE("Invalid WMA handle");
2319 return CDF_STATUS_E_NULL_VALUE;
2320 }
2321
2322 param_buf = (WMI_SOC_HW_MODE_TRANSITION_EVENTID_param_tlvs *) event;
2323 if (!param_buf) {
2324 /* This is an async event. So, not sending any event to LIM */
2325 WMA_LOGE("Invalid WMI_SOC_HW_MODE_TRANSITION_EVENTID event");
2326 return CDF_STATUS_E_FAILURE;
2327 }
2328
2329 hw_mode_trans_ind = cdf_mem_malloc(sizeof(*hw_mode_trans_ind));
2330 if (!hw_mode_trans_ind) {
2331 WMA_LOGI("%s: Memory allocation failed", __func__);
2332 return CDF_STATUS_E_NULL_VALUE;
2333 }
2334
2335 wmi_event = param_buf->fixed_param;
2336 hw_mode_trans_ind->old_hw_mode_index = wmi_event->old_hw_mode_index;
2337 hw_mode_trans_ind->new_hw_mode_index = wmi_event->new_hw_mode_index;
2338 hw_mode_trans_ind->num_vdev_mac_entries =
2339 wmi_event->num_vdev_mac_entries;
2340 WMA_LOGI("%s: old_hw_mode_index:%d new_hw_mode_index:%d entries=%d",
2341 __func__, wmi_event->old_hw_mode_index,
2342 wmi_event->new_hw_mode_index, wmi_event->num_vdev_mac_entries);
2343
2344 vdev_mac_entry =
2345 param_buf->wmi_soc_set_hw_mode_response_vdev_mac_mapping;
2346
2347 /* Store the vdev-mac map in WMA and prepare to send to HDD */
2348 for (i = 0; i < wmi_event->num_vdev_mac_entries; i++) {
2349 uint32_t vdev_id, mac_id;
2350 vdev_id = vdev_mac_entry[i].vdev_id;
2351 mac_id = vdev_mac_entry[i].mac_id;
2352
2353 WMA_LOGI("%s: vdev_id:%d mac_id:%d",
2354 __func__, vdev_id, mac_id);
2355
2356 hw_mode_trans_ind->vdev_mac_map[i].vdev_id = vdev_id;
2357 hw_mode_trans_ind->vdev_mac_map[i].mac_id = mac_id;
2358 wma_update_intf_hw_mode_params(vdev_id, mac_id,
2359 wmi_event->new_hw_mode_index);
2360 }
2361 wma->old_hw_mode_index = wmi_event->old_hw_mode_index;
2362 wma->new_hw_mode_index = wmi_event->new_hw_mode_index;
2363
2364 WMA_LOGI("%s: Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
2365 __func__, wma->old_hw_mode_index, wma->new_hw_mode_index);
2366
2367 /* Pass the message to PE */
2368 wma_send_msg(wma, SIR_HAL_SOC_HW_MODE_TRANS_IND,
2369 (void *) hw_mode_trans_ind, 0);
2370
2371 return CDF_STATUS_SUCCESS;
2372}
2373
2374/**
2375 * wma_soc_set_dual_mode_config_resp_evt_handler() - Dual mode evt handler
2376 * @handle: WMI handle
2377 * @event: Event received from FW
2378 * @len: Length of the event
2379 *
2380 * Notifies the host driver of the completion or failure of a
2381 * WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID command. This event would be returned to
2382 * the host driver once the firmware has completed a reconfiguration of the Scan
2383 * and FW mode configuration. This changes could include entering or leaving a
2384 * dual mac configuration for either scan and/or more permanent firmware mode.
2385 *
2386 * Return: Success on receiving valid params from FW
2387 */
2388static int wma_soc_set_dual_mode_config_resp_evt_handler(void *handle,
2389 uint8_t *event,
2390 uint32_t len)
2391{
2392 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID_param_tlvs *param_buf;
2393 wmi_soc_set_dual_mac_config_response_event_fixed_param *wmi_event;
2394 tp_wma_handle wma = (tp_wma_handle) handle;
2395 struct sir_dual_mac_config_resp *dual_mac_cfg_resp;
2396
2397 if (!wma) {
2398 WMA_LOGE("%s: Invalid WMA handle", __func__);
2399 /* Since the WMA handle is NULL, we cannot send resp to LIM.
2400 * So, returning from here.
2401 */
2402 return CDF_STATUS_E_NULL_VALUE;
2403 }
2404
2405 dual_mac_cfg_resp = cdf_mem_malloc(sizeof(*dual_mac_cfg_resp));
2406 if (!dual_mac_cfg_resp) {
2407 WMA_LOGE("%s: Memory allocation failed", __func__);
2408 /* Since the mem alloc failed, we cannot send resp to LIM.
2409 * So, returning from here.
2410 */
2411 return CDF_STATUS_E_NULL_VALUE;
2412 }
2413
2414 param_buf = (WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID_param_tlvs *)
2415 event;
2416 if (!param_buf) {
2417 WMA_LOGE("%s: Invalid event", __func__);
2418 goto fail;
2419 }
2420
2421 wmi_event = param_buf->fixed_param;
2422 WMA_LOGI("%s: status:%d", __func__, wmi_event->status);
2423 dual_mac_cfg_resp->status = wmi_event->status;
2424
2425 if (SET_HW_MODE_STATUS_OK == dual_mac_cfg_resp->status) {
2426 wma->dual_mac_cfg.prev_scan_config =
2427 wma->dual_mac_cfg.cur_scan_config;
2428 wma->dual_mac_cfg.prev_fw_mode_config =
2429 wma->dual_mac_cfg.cur_fw_mode_config;
2430 wma->dual_mac_cfg.cur_scan_config =
2431 wma->dual_mac_cfg.req_scan_config;
2432 wma->dual_mac_cfg.cur_fw_mode_config =
2433 wma->dual_mac_cfg.req_fw_mode_config;
2434 }
2435
2436 /* Pass the message to PE */
2437 wma_send_msg(wma, SIR_HAL_SOC_DUAL_MAC_CFG_RESP,
2438 (void *) dual_mac_cfg_resp, 0);
2439
2440 return CDF_STATUS_SUCCESS;
2441
2442fail:
2443 WMA_LOGE("%s: Sending fail response to LIM", __func__);
2444 dual_mac_cfg_resp->status = SET_HW_MODE_STATUS_ECANCELED;
2445 wma_send_msg(wma, SIR_HAL_SOC_DUAL_MAC_CFG_RESP,
2446 (void *) dual_mac_cfg_resp, 0);
2447
2448 return CDF_STATUS_E_FAILURE;
2449
2450}
2451
2452/**
2453 * wma_start() - wma start function.
2454 * Intialize event handlers and timers.
2455 * @cds_ctx: cds context
2456 *
2457 * Return: 0 on success, CDF Error on failure
2458 */
2459CDF_STATUS wma_start(void *cds_ctx)
2460{
2461 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
2462 tp_wma_handle wma_handle;
2463 int status;
2464 WMA_LOGD("%s: Enter", __func__);
2465
2466 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
2467
2468 /* validate the wma_handle */
2469 if (NULL == wma_handle) {
2470 WMA_LOGP("%s: Invalid handle", __func__);
2471 cdf_status = CDF_STATUS_E_INVAL;
2472 goto end;
2473 }
2474
2475 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2476 WMI_SCAN_EVENTID,
2477 wma_scan_event_callback);
2478 if (0 != status) {
2479 WMA_LOGP("%s: Failed to register scan callback", __func__);
2480 cdf_status = CDF_STATUS_E_FAILURE;
2481 goto end;
2482 }
2483
2484 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2485 WMI_ROAM_EVENTID,
2486 wma_roam_event_callback);
2487 if (0 != status) {
2488 WMA_LOGP("%s: Failed to register Roam callback", __func__);
2489 cdf_status = CDF_STATUS_E_FAILURE;
2490 goto end;
2491 }
2492
2493 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2494 WMI_WOW_WAKEUP_HOST_EVENTID,
2495 wma_wow_wakeup_host_event);
2496 if (status) {
2497 WMA_LOGP("%s: Failed to register wow wakeup host event handler",
2498 __func__);
2499 cdf_status = CDF_STATUS_E_FAILURE;
2500 goto end;
2501 }
2502
2503 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2504 WMI_PDEV_RESUME_EVENTID,
2505 wma_pdev_resume_event_handler);
2506 if (status) {
2507 WMA_LOGP("%s: Failed to register PDEV resume event handler",
2508 __func__);
2509 cdf_status = CDF_STATUS_E_FAILURE;
2510 goto end;
2511 }
2512
2513#ifdef FEATURE_WLAN_SCAN_PNO
2514 if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
2515 WMI_SERVICE_NLO)) {
2516
2517 WMA_LOGD("FW supports pno offload, registering nlo match handler");
2518
2519 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2520 WMI_NLO_MATCH_EVENTID,
2521 wma_nlo_match_evt_handler);
2522 if (status) {
2523 WMA_LOGE("Failed to register nlo match event cb");
2524 cdf_status = CDF_STATUS_E_FAILURE;
2525 goto end;
2526 }
2527
2528 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2529 WMI_NLO_SCAN_COMPLETE_EVENTID,
2530 wma_nlo_scan_cmp_evt_handler);
2531 if (status) {
2532 WMA_LOGE("Failed to register nlo scan comp event cb");
2533 cdf_status = CDF_STATUS_E_FAILURE;
2534 goto end;
2535 }
2536 }
2537#endif /* FEATURE_WLAN_SCAN_PNO */
2538
2539#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
2540 WMA_LOGE("MCC TX Pause Event Handler register");
2541 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2542 WMI_TX_PAUSE_EVENTID,
2543 wma_mcc_vdev_tx_pause_evt_handler);
2544#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
2545
2546#ifdef FEATURE_WLAN_CH_AVOID
2547 WMA_LOGD("Registering channel to avoid handler");
2548
2549 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2550 WMI_WLAN_FREQ_AVOID_EVENTID,
2551 wma_channel_avoid_evt_handler);
2552 if (status) {
2553 WMA_LOGE("Failed to register channel to avoid event cb");
2554 cdf_status = CDF_STATUS_E_FAILURE;
2555 goto end;
2556 }
2557#endif /* FEATURE_WLAN_CH_AVOID */
2558#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2559 WMA_LOGD("Registering auto shutdown handler");
2560 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2561 WMI_HOST_AUTO_SHUTDOWN_EVENTID,
2562 wma_auto_shutdown_event_handler);
2563 if (status) {
2564 WMA_LOGE("Failed to register WMI Auto shutdown event handler");
2565 cdf_status = CDF_STATUS_E_FAILURE;
2566 goto end;
2567 }
2568#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
2569 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2570 WMI_THERMAL_MGMT_EVENTID,
2571 wma_thermal_mgmt_evt_handler);
2572 if (status) {
2573 WMA_LOGE("Failed to register thermal mitigation event cb");
2574 cdf_status = CDF_STATUS_E_FAILURE;
2575 goto end;
2576 }
2577
2578 status = wma_ocb_register_event_handlers(wma_handle);
2579 if (status) {
2580 WMA_LOGE("Failed to register ocb event handlers");
2581 cdf_status = CDF_STATUS_E_FAILURE;
2582 goto end;
2583 }
2584
2585 cdf_status = CDF_STATUS_SUCCESS;
2586
2587#ifdef QCA_WIFI_FTM
2588 /*
2589 * Tx mgmt attach requires TXRX context which is not created
2590 * in FTM mode. So skip the TX mgmt attach.
2591 */
2592 if (cds_get_conparam() == CDF_FTM_MODE)
2593 goto end;
2594#endif /* QCA_WIFI_FTM */
2595
2596 cdf_status = wma_tx_attach(wma_handle);
2597 if (cdf_status != CDF_STATUS_SUCCESS) {
2598 WMA_LOGP("%s: Failed to register tx management", __func__);
2599 goto end;
2600 }
2601
2602 /* Initialize log completion timeout */
2603 cdf_status = cdf_mc_timer_init(&wma_handle->log_completion_timer,
2604 CDF_TIMER_TYPE_SW,
2605 wma_log_completion_timeout,
2606 wma_handle);
2607 if (cdf_status != CDF_STATUS_SUCCESS) {
2608 WMA_LOGE("Failed to initialize log completion timeout");
2609 goto end;
2610 }
2611
2612 /* Initialize the get temperature event handler */
2613 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2614 WMI_PDEV_TEMPERATURE_EVENTID,
2615 wma_pdev_temperature_evt_handler);
2616 if (status != CDF_STATUS_SUCCESS) {
2617 WMA_LOGE("Failed to register get_temperature event cb");
2618 cdf_status = CDF_STATUS_E_FAILURE;
2619 goto end;
2620 }
2621
2622 /* Initialize the log flush complete event handler */
2623 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2624 WMI_DEBUG_MESG_FLUSH_COMPLETE_EVENTID,
2625 wma_flush_complete_evt_handler);
2626 if (status != CDF_STATUS_SUCCESS) {
2627 WMA_LOGE("Failed to register log flush complete event cb");
2628 cdf_status = CDF_STATUS_E_FAILURE;
2629 goto end;
2630 }
2631
2632 /* Initialize the WMI_SOC_SET_HW_MODE_RESP_EVENTID event handler */
2633 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2634 WMI_SOC_SET_HW_MODE_RESP_EVENTID,
2635 wma_soc_set_hw_mode_resp_evt_handler);
2636 if (status != CDF_STATUS_SUCCESS) {
2637 WMA_LOGE("Failed to register set hw mode resp event cb");
2638 cdf_status = CDF_STATUS_E_FAILURE;
2639 goto end;
2640 }
2641
2642 /* Initialize the WMI_SOC_HW_MODE_TRANSITION_EVENTID event handler */
2643 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2644 WMI_SOC_HW_MODE_TRANSITION_EVENTID,
2645 wma_soc_hw_mode_transition_evt_handler);
2646 if (status != CDF_STATUS_SUCCESS) {
2647 WMA_LOGE("Failed to register hw mode transition event cb");
2648 cdf_status = CDF_STATUS_E_FAILURE;
2649 goto end;
2650 }
2651
2652 /* Initialize the set dual mac configuration event handler */
2653 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
2654 WMI_SOC_SET_DUAL_MAC_CONFIG_RESP_EVENTID,
2655 wma_soc_set_dual_mode_config_resp_evt_handler);
2656 if (status != CDF_STATUS_SUCCESS) {
2657 WMA_LOGE("Failed to register hw mode transition event cb");
2658 cdf_status = CDF_STATUS_E_FAILURE;
2659 goto end;
2660 }
2661
2662 cdf_status = cdf_event_init(&wma_handle->service_ready_ext_evt);
2663 if (CDF_STATUS_SUCCESS != cdf_status) {
2664 WMA_LOGE("Unable to init service_ready_ext_evt");
2665 goto end;
2666 }
2667
2668end:
2669 WMA_LOGD("%s: Exit", __func__);
2670 return cdf_status;
2671}
2672
2673/**
2674 * wma_stop() - wma stop function.
2675 * cleanup timers and suspend target.
2676 * @cds_ctx: cds context
2677 * @reason: reason for wma_stop.
2678 *
2679 * Return: 0 on success, CDF Error on failure
2680 */
2681CDF_STATUS wma_stop(void *cds_ctx, uint8_t reason)
2682{
2683 tp_wma_handle wma_handle;
2684 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
2685
2686 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
2687
2688 WMA_LOGD("%s: Enter", __func__);
2689
2690 /* validate the wma_handle */
2691 if (NULL == wma_handle) {
2692 WMA_LOGP("%s: Invalid handle", __func__);
2693 cdf_status = CDF_STATUS_E_INVAL;
2694 goto end;
2695 }
2696#ifdef QCA_WIFI_FTM
2697 /*
2698 * Tx mgmt detach requires TXRX context which is not created
2699 * in FTM mode. So skip the TX mgmt detach.
2700 */
2701 if (cds_get_conparam() == CDF_FTM_MODE) {
2702 cdf_status = CDF_STATUS_SUCCESS;
2703 goto end;
2704 }
2705#endif /* QCA_WIFI_FTM */
2706
2707 if (wma_handle->ack_work_ctx) {
2708 cds_flush_work(&wma_handle->ack_work_ctx->ack_cmp_work);
2709 cdf_mem_free(wma_handle->ack_work_ctx);
2710 wma_handle->ack_work_ctx = NULL;
2711 }
2712
2713 /* Destroy the timer for log completion */
2714 cdf_status = cdf_mc_timer_destroy(&wma_handle->log_completion_timer);
2715 if (cdf_status != CDF_STATUS_SUCCESS) {
2716 WMA_LOGE("Failed to destroy the log completion timer");
2717 }
2718
2719 /* There's no need suspend target which is already down during SSR. */
2720 if (!cds_is_logp_in_progress()) {
2721#ifdef HIF_USB
2722 /* Suspend the target and enable interrupt */
2723 if (wma_suspend_target(wma_handle, 0))
2724 WMA_LOGE("Failed to suspend target");
2725#else
2726 /* Suspend the target and disable interrupt */
2727 if (wma_suspend_target(wma_handle, 1))
2728 WMA_LOGE("Failed to suspend target");
2729#endif /* HIF_USB */
2730 }
2731
2732 cdf_status = wma_tx_detach(wma_handle);
2733 if (cdf_status != CDF_STATUS_SUCCESS) {
2734 WMA_LOGP("%s: Failed to deregister tx management", __func__);
2735 goto end;
2736 }
2737
2738 cdf_status = cdf_event_destroy(&wma_handle->service_ready_ext_evt);
2739 if (cdf_status != CDF_STATUS_SUCCESS) {
2740 WMA_LOGE("Failed to destroy service_ready_ext_evt");
2741 goto end;
2742 }
2743
2744end:
2745 WMA_LOGD("%s: Exit", __func__);
2746 return cdf_status;
2747}
2748
2749/**
2750 * wma_cleanup_hold_req() - cleanup hold request queue
2751 * @wma: wma handle
2752 *
2753 * Return: none
2754 */
2755static void wma_cleanup_hold_req(tp_wma_handle wma)
2756{
2757 struct wma_target_req *req_msg = NULL;
2758 cdf_list_node_t *node1 = NULL, *node2 = NULL;
2759 CDF_STATUS status;
2760
2761 cdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
2762 if (CDF_STATUS_SUCCESS != cdf_list_peek_front(&wma->wma_hold_req_queue,
2763 &node2)) {
2764 cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
2765 WMA_LOGI(FL("request queue maybe empty"));
2766 return;
2767 }
2768
2769 do {
2770 node1 = node2;
2771 req_msg = (struct wma_target_req *)node1;
2772 status = cdf_list_remove_node(&wma->wma_hold_req_queue, node1);
2773 if (CDF_STATUS_SUCCESS != status) {
2774 cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
2775 WMA_LOGE(FL("Failed to remove request for vdev_id %d type %d"),
2776 req_msg->vdev_id, req_msg->type);
2777 return;
2778 } else {
2779 cdf_mc_timer_destroy(&req_msg->event_timeout);
2780 cdf_mem_free(req_msg);
2781 }
2782 } while (CDF_STATUS_SUCCESS ==
2783 cdf_list_peek_next(&wma->wma_hold_req_queue, node1,
2784 &node2));
2785
2786 cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
2787}
2788
2789/**
2790 * wma_cleanup_vdev_resp() - cleanup vdev response queue
2791 * @wma: wma handle
2792 *
2793 * Return: none
2794 */
2795static void wma_cleanup_vdev_resp(tp_wma_handle wma)
2796{
2797 struct wma_target_req *msg, *tmp;
2798
2799 cdf_spin_lock_bh(&wma->vdev_respq_lock);
2800 list_for_each_entry_safe(msg, tmp, &wma->vdev_resp_queue, node) {
2801 list_del(&msg->node);
2802 cdf_mc_timer_destroy(&msg->event_timeout);
2803 cdf_mem_free(msg);
2804 }
2805 cdf_spin_unlock_bh(&wma->vdev_respq_lock);
2806}
2807
2808/**
2809 * wma_wmi_service_close() - close wma wmi service interface.
2810 * @cds_ctx: cds context
2811 *
2812 * Return: 0 on success, CDF Error on failure
2813 */
2814CDF_STATUS wma_wmi_service_close(void *cds_ctx)
2815{
2816 tp_wma_handle wma_handle;
2817 struct beacon_info *bcn;
2818 int i;
2819
2820 WMA_LOGD("%s: Enter", __func__);
2821
2822 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
2823
2824 /* validate the wma_handle */
2825 if (NULL == wma_handle) {
2826 WMA_LOGE("%s: Invalid wma handle", __func__);
2827 return CDF_STATUS_E_INVAL;
2828 }
2829
2830 /* validate the wmi handle */
2831 if (NULL == wma_handle->wmi_handle) {
2832 WMA_LOGE("%s: Invalid wmi handle", __func__);
2833 return CDF_STATUS_E_INVAL;
2834 }
2835
2836 /* dettach the wmi serice */
2837 WMA_LOGD("calling wmi_unified_detach");
2838 wmi_unified_detach(wma_handle->wmi_handle);
2839 wma_handle->wmi_handle = NULL;
2840
2841 for (i = 0; i < wma_handle->max_bssid; i++) {
2842 bcn = wma_handle->interfaces[i].beacon;
2843
2844 if (bcn) {
2845 if (bcn->dma_mapped)
2846 cdf_nbuf_unmap_single(wma_handle->cdf_dev,
2847 bcn->buf, CDF_DMA_TO_DEVICE);
2848 cdf_nbuf_free(bcn->buf);
2849 cdf_mem_free(bcn);
2850 wma_handle->interfaces[i].beacon = NULL;
2851 }
2852
2853 if (wma_handle->interfaces[i].handle) {
2854 cdf_mem_free(wma_handle->interfaces[i].handle);
2855 wma_handle->interfaces[i].handle = NULL;
2856 }
2857 }
2858
2859 cdf_mem_free(wma_handle->interfaces);
2860 /* free the wma_handle */
2861 cds_free_context(wma_handle->cds_context, CDF_MODULE_ID_WMA,
2862 wma_handle);
2863
2864 cdf_mem_free(((p_cds_contextType) cds_ctx)->cfg_ctx);
2865 WMA_LOGD("%s: Exit", __func__);
2866 return CDF_STATUS_SUCCESS;
2867}
2868
2869
2870
2871/**
2872 * wma_close() - wma close function.
2873 * cleanup resources attached with wma.
2874 * @cds_ctx: cds context
2875 *
2876 * Return: 0 on success, CDF Error on failure
2877 */
2878CDF_STATUS wma_close(void *cds_ctx)
2879{
2880 tp_wma_handle wma_handle;
2881 uint32_t idx;
2882 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
2883
2884 WMA_LOGD("%s: Enter", __func__);
2885
2886 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
2887
2888 /* validate the wma_handle */
2889 if (NULL == wma_handle) {
2890 WMA_LOGE("%s: Invalid wma handle", __func__);
2891 return CDF_STATUS_E_INVAL;
2892 }
2893
2894 /* validate the wmi handle */
2895 if (NULL == wma_handle->wmi_handle) {
2896 WMA_LOGP("%s: Invalid wmi handle", __func__);
2897 return CDF_STATUS_E_INVAL;
2898 }
2899
2900 /* Free DBS list */
2901 if (wma_handle->hw_mode.hw_mode_list) {
2902 cdf_mem_free(wma_handle->hw_mode.hw_mode_list);
2903 wma_handle->hw_mode.hw_mode_list = NULL;
2904 WMA_LOGI("%s: DBS list is freed", __func__);
2905 }
2906
2907 if (wma_handle->events_logs_list) {
2908 cdf_mem_free(wma_handle->events_logs_list);
2909 wma_handle->events_logs_list = NULL;
2910 WMA_LOGD("%s: Event log list freed", __func__);
2911 }
2912
2913 if (wma_handle->saved_wmi_init_cmd.buf) {
2914 wmi_buf_free(wma_handle->saved_wmi_init_cmd.buf);
2915 wma_handle->saved_wmi_init_cmd.buf = NULL;
2916 }
2917
2918 if (cds_get_conparam() != CDF_FTM_MODE) {
2919#ifdef FEATURE_WLAN_SCAN_PNO
2920 cdf_wake_lock_destroy(&wma_handle->pno_wake_lock);
2921#endif /* FEATURE_WLAN_SCAN_PNO */
2922#ifdef FEATURE_WLAN_EXTSCAN
2923 cdf_wake_lock_destroy(&wma_handle->extscan_wake_lock);
2924#endif /* FEATURE_WLAN_EXTSCAN */
2925 cdf_wake_lock_destroy(&wma_handle->wow_wake_lock);
2926 }
2927
2928 /* unregister Firmware debug log */
2929 cdf_status = dbglog_deinit(wma_handle->wmi_handle);
2930 if (cdf_status != CDF_STATUS_SUCCESS)
2931 WMA_LOGP("%s: dbglog_deinit failed", __func__);
2932
2933 /* close the cdf events */
2934 cdf_event_destroy(&wma_handle->wma_ready_event);
2935 cdf_event_destroy(&wma_handle->target_suspend);
2936 cdf_event_destroy(&wma_handle->wma_resume_event);
2937 cdf_event_destroy(&wma_handle->recovery_event);
2938 wma_cleanup_vdev_resp(wma_handle);
2939 wma_cleanup_hold_req(wma_handle);
2940 for (idx = 0; idx < wma_handle->num_mem_chunks; ++idx) {
2941 cdf_os_mem_free_consistent(wma_handle->cdf_dev,
2942 wma_handle->mem_chunks[idx].len,
2943 wma_handle->mem_chunks[idx].vaddr,
2944 wma_handle->mem_chunks[idx].paddr,
2945 cdf_get_dma_mem_context(
2946 (&(wma_handle->mem_chunks[idx])),
2947 memctx));
2948 }
2949
2950#if defined(QCA_WIFI_FTM)
2951 /* Detach UTF and unregister the handler */
2952 if (cds_get_conparam() == CDF_FTM_MODE)
2953 wma_utf_detach(wma_handle);
2954#endif /* QCA_WIFI_FTM */
2955
2956 if (NULL != wma_handle->dfs_ic) {
2957 wma_dfs_detach(wma_handle->dfs_ic);
2958 wma_handle->dfs_ic = NULL;
2959 }
2960
2961 if (NULL != wma_handle->pGetRssiReq) {
2962 cdf_mem_free(wma_handle->pGetRssiReq);
2963 wma_handle->pGetRssiReq = NULL;
2964 }
2965 if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
2966 WMI_SERVICE_MGMT_TX_WMI)) {
2967 wmi_desc_pool_deinit(wma_handle);
2968 }
2969
2970 WMA_LOGD("%s: Exit", __func__);
2971 return CDF_STATUS_SUCCESS;
2972}
2973
2974/**
2975 * wma_update_fw_config() - update fw configuration
2976 * @wma_handle: wma handle
2977 * @tgt_cap: target capabality
2978 *
2979 * Return: none
2980 */
2981static void wma_update_fw_config(tp_wma_handle wma_handle,
2982 struct wma_target_cap *tgt_cap)
2983{
2984 /*
2985 * tgt_cap contains default target resource configuration
2986 * which can be modified here, if required
2987 */
2988 /* Override the no. of max fragments as per platform configuration */
2989 tgt_cap->wlan_resource_config.max_frag_entries =
2990 CDF_MIN(QCA_OL_11AC_TX_MAX_FRAGS,
2991 wma_handle->max_frag_entry);
2992 wma_handle->max_frag_entry =
2993 tgt_cap->wlan_resource_config.max_frag_entries;
2994}
2995
2996/**
2997 * wma_alloc_host_mem_chunk() - allocate host memory
2998 * @wma_handle: wma handle
2999 * @req_id: request id
3000 * @idx: index
3001 * @num_units: number of units
3002 * @unit_len: unit length
3003 *
3004 * allocate a chunk of memory at the index indicated and
3005 * if allocation fail allocate smallest size possiblr and
3006 * return number of units allocated.
3007 *
3008 * Return: number of units or 0 for error.
3009 */
3010static uint32_t wma_alloc_host_mem_chunk(tp_wma_handle wma_handle,
3011 uint32_t req_id, uint32_t idx,
3012 uint32_t num_units, uint32_t unit_len)
3013{
3014 cdf_dma_addr_t paddr;
3015 if (!num_units || !unit_len) {
3016 return 0;
3017 }
3018 wma_handle->mem_chunks[idx].vaddr = NULL;
3019 /** reduce the requested allocation by half until allocation succeeds */
3020 while (wma_handle->mem_chunks[idx].vaddr == NULL && num_units) {
3021 wma_handle->mem_chunks[idx].vaddr =
3022 cdf_os_mem_alloc_consistent(wma_handle->cdf_dev,
3023 num_units * unit_len, &paddr,
3024 cdf_get_dma_mem_context(
3025 (&(wma_handle->mem_chunks[idx])),
3026 memctx));
3027 if (wma_handle->mem_chunks[idx].vaddr == NULL) {
3028 num_units = (num_units >> 1);/* reduce length by half */
3029 } else {
3030 wma_handle->mem_chunks[idx].paddr = paddr;
3031 wma_handle->mem_chunks[idx].len = num_units * unit_len;
3032 wma_handle->mem_chunks[idx].req_id = req_id;
3033 }
3034 }
3035 return num_units;
3036}
3037
3038#define HOST_MEM_SIZE_UNIT 4
3039/**
3040 * wma_alloc_host_mem() - allocate amount of memory requested by FW.
3041 * @wma_handle: wma handle
3042 * @req_id: request id
3043 * @num_units: number of units
3044 * @unit_len: unit length
3045 *
3046 * Return: none
3047 */
3048static void wma_alloc_host_mem(tp_wma_handle wma_handle, uint32_t req_id,
3049 uint32_t num_units, uint32_t unit_len)
3050{
3051 uint32_t remaining_units, allocated_units, idx;
3052
3053 /* adjust the length to nearest multiple of unit size */
3054 unit_len = (unit_len + (HOST_MEM_SIZE_UNIT - 1)) &
3055 (~(HOST_MEM_SIZE_UNIT - 1));
3056 idx = wma_handle->num_mem_chunks;
3057 remaining_units = num_units;
3058 while (remaining_units) {
3059 allocated_units = wma_alloc_host_mem_chunk(wma_handle, req_id,
3060 idx, remaining_units,
3061 unit_len);
3062 if (allocated_units == 0) {
3063 WMA_LOGE("FAILED TO ALLOCATED memory unit len %d"
3064 " units requested %d units allocated %d ",
3065 unit_len, num_units,
3066 (num_units - remaining_units));
3067 wma_handle->num_mem_chunks = idx;
3068 break;
3069 }
3070 remaining_units -= allocated_units;
3071 ++idx;
3072 if (idx == MAX_MEM_CHUNKS) {
3073 WMA_LOGE("RWACHED MAX CHUNK LIMIT for memory units %d"
3074 " unit len %d requested by FW,"
3075 " only allocated %d ",
3076 num_units, unit_len,
3077 (num_units - remaining_units));
3078 wma_handle->num_mem_chunks = idx;
3079 break;
3080 }
3081 }
3082 wma_handle->num_mem_chunks = idx;
3083}
3084
3085/**
3086 * wma_update_target_services() - update target services from wma handle
3087 * @wh: wma handle
3088 * @cfg: target services
3089 *
3090 * Return: none
3091 */
3092static inline void wma_update_target_services(tp_wma_handle wh,
3093 struct wma_tgt_services *cfg)
3094{
3095 /* STA power save */
3096 cfg->sta_power_save = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3097 WMI_SERVICE_STA_PWRSAVE);
3098
3099 /* Enable UAPSD */
3100 cfg->uapsd = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3101 WMI_SERVICE_AP_UAPSD);
3102
3103 /* Update AP DFS service */
3104 cfg->ap_dfs = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3105 WMI_SERVICE_AP_DFS);
3106
3107 /* Enable 11AC */
3108 cfg->en_11ac = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3109 WMI_SERVICE_11AC);
3110 if (cfg->en_11ac)
3111 g_fw_wlan_feat_caps |= (1 << DOT11AC);
3112
3113 /* Proactive ARP response */
3114 g_fw_wlan_feat_caps |= (1 << WLAN_PERIODIC_TX_PTRN);
3115
3116 /* Enable WOW */
3117 g_fw_wlan_feat_caps |= (1 << WOW);
3118
3119 /* ARP offload */
3120 cfg->arp_offload = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3121 WMI_SERVICE_ARPNS_OFFLOAD);
3122
3123 /* Adaptive early-rx */
3124 cfg->early_rx = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3125 WMI_SERVICE_EARLY_RX);
3126#ifdef FEATURE_WLAN_SCAN_PNO
3127 /* PNO offload */
3128 if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_NLO))
3129 cfg->pno_offload = true;
3130#endif /* FEATURE_WLAN_SCAN_PNO */
3131
3132#ifdef FEATURE_WLAN_EXTSCAN
3133 if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_EXTSCAN)) {
3134 g_fw_wlan_feat_caps |= (1 << EXTENDED_SCAN);
3135 }
3136#endif /* FEATURE_WLAN_EXTSCAN */
3137 cfg->lte_coex_ant_share = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3138 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT);
3139#ifdef FEATURE_WLAN_TDLS
3140 /* Enable TDLS */
3141 if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_TDLS)) {
3142 cfg->en_tdls = 1;
3143 g_fw_wlan_feat_caps |= (1 << TDLS);
3144 }
3145 /* Enable advanced TDLS features */
3146 if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3147 WMI_SERVICE_TDLS_OFFCHAN)) {
3148 cfg->en_tdls_offchan = 1;
3149 g_fw_wlan_feat_caps |= (1 << TDLS_OFF_CHANNEL);
3150 }
3151
3152 cfg->en_tdls_uapsd_buf_sta =
3153 WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3154 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA);
3155 cfg->en_tdls_uapsd_sleep_sta =
3156 WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3157 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA);
3158#endif /* FEATURE_WLAN_TDLS */
3159 if (WMI_SERVICE_IS_ENABLED
3160 (wh->wmi_service_bitmap, WMI_SERVICE_BEACON_OFFLOAD))
3161 cfg->beacon_offload = true;
3162#ifdef WLAN_FEATURE_ROAM_OFFLOAD
3163 /* Enable Roam Offload */
3164 cfg->en_roam_offload = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
3165 WMI_SERVICE_ROAM_HO_OFFLOAD);
3166#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
3167#ifdef WLAN_FEATURE_NAN
3168 if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_NAN))
3169 g_fw_wlan_feat_caps |= (1 << NAN);
3170#endif /* WLAN_FEATURE_NAN */
3171
3172 if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_RTT))
3173 g_fw_wlan_feat_caps |= (1 << RTT);
3174}
3175
3176/**
3177 * wma_update_target_ht_cap() - update ht capabality from wma handle
3178 * @wh: wma handle
3179 * @cfg: ht capabality
3180 *
3181 * Return: none
3182 */
3183static inline void wma_update_target_ht_cap(tp_wma_handle wh,
3184 struct wma_tgt_ht_cap *cfg)
3185{
3186 /* RX STBC */
3187 cfg->ht_rx_stbc = !!(wh->ht_cap_info & WMI_HT_CAP_RX_STBC);
3188
3189 /* TX STBC */
3190 cfg->ht_tx_stbc = !!(wh->ht_cap_info & WMI_HT_CAP_TX_STBC);
3191
3192 /* MPDU density */
3193 cfg->mpdu_density = wh->ht_cap_info & WMI_HT_CAP_MPDU_DENSITY;
3194
3195 /* HT RX LDPC */
3196 cfg->ht_rx_ldpc = !!(wh->ht_cap_info & WMI_HT_CAP_LDPC);
3197
3198 /* HT SGI */
3199 cfg->ht_sgi_20 = !!(wh->ht_cap_info & WMI_HT_CAP_HT20_SGI);
3200
3201 cfg->ht_sgi_40 = !!(wh->ht_cap_info & WMI_HT_CAP_HT40_SGI);
3202
3203 /* RF chains */
3204 cfg->num_rf_chains = wh->num_rf_chains;
3205
3206 WMA_LOGD("%s: ht_cap_info - %x ht_rx_stbc - %d, ht_tx_stbc - %d\n\
3207 mpdu_density - %d ht_rx_ldpc - %d ht_sgi_20 - %d\n\
3208 ht_sgi_40 - %d num_rf_chains - %d ", __func__, wh->ht_cap_info,
3209 cfg->ht_rx_stbc, cfg->ht_tx_stbc, cfg->mpdu_density,
3210 cfg->ht_rx_ldpc, cfg->ht_sgi_20, cfg->ht_sgi_40,
3211 cfg->num_rf_chains);
3212
3213}
3214
3215#ifdef WLAN_FEATURE_11AC
3216/**
3217 * wma_update_target_vht_cap() - update vht capabality from wma handle
3218 * @wh: wma handle
3219 * @cfg: vht capabality
3220 *
3221 * Return: none
3222 */
3223static inline void wma_update_target_vht_cap(tp_wma_handle wh,
3224 struct wma_tgt_vht_cap *cfg)
3225{
3226
3227 if (wh->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_11454)
3228 cfg->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_11454;
3229 else if (wh->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_7935)
3230 cfg->vht_max_mpdu = WMI_VHT_CAP_MAX_MPDU_LEN_7935;
3231 else
3232 cfg->vht_max_mpdu = 0;
3233
3234
3235 if (wh->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_80P80_160MHZ) {
3236 cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80P80MHZ;
3237 cfg->supp_chan_width |= 1 << eHT_CHANNEL_WIDTH_160MHZ;
3238 } else if (wh->vht_cap_info & WMI_VHT_CAP_CH_WIDTH_160MHZ)
3239 cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_160MHZ;
3240 else
3241 cfg->supp_chan_width = 1 << eHT_CHANNEL_WIDTH_80MHZ;
3242
3243 cfg->vht_rx_ldpc = wh->vht_cap_info & WMI_VHT_CAP_RX_LDPC;
3244
3245 cfg->vht_short_gi_80 = wh->vht_cap_info & WMI_VHT_CAP_SGI_80MHZ;
3246 cfg->vht_short_gi_160 = wh->vht_cap_info & WMI_VHT_CAP_SGI_160MHZ;
3247
3248 cfg->vht_tx_stbc = wh->vht_cap_info & WMI_VHT_CAP_TX_STBC;
3249
3250 cfg->vht_rx_stbc = (wh->vht_cap_info & WMI_VHT_CAP_RX_STBC_1SS) |
3251 (wh->vht_cap_info & WMI_VHT_CAP_RX_STBC_2SS) |
3252 (wh->vht_cap_info & WMI_VHT_CAP_RX_STBC_3SS) ;
3253
3254 cfg->vht_max_ampdu_len_exp = (wh->vht_cap_info &
3255 WMI_VHT_CAP_MAX_AMPDU_LEN_EXP)
3256 >> WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT;
3257
3258 cfg->vht_su_bformer = wh->vht_cap_info & WMI_VHT_CAP_SU_BFORMER;
3259
3260 cfg->vht_su_bformee = wh->vht_cap_info & WMI_VHT_CAP_SU_BFORMEE;
3261
3262 cfg->vht_mu_bformer = wh->vht_cap_info & WMI_VHT_CAP_MU_BFORMER;
3263
3264 cfg->vht_mu_bformee = wh->vht_cap_info & WMI_VHT_CAP_MU_BFORMEE;
3265
3266 cfg->vht_txop_ps = wh->vht_cap_info & WMI_VHT_CAP_TXOP_PS;
3267
3268 WMA_LOGD(" %s: max_mpdu %d supp_chan_width %x rx_ldpc %x\n \
3269 short_gi_80 %x tx_stbc %x rx_stbc %x txop_ps %x\n \
3270 su_bformee %x mu_bformee %x max_ampdu_len_exp %d", __func__,
3271 cfg->vht_max_mpdu, cfg->supp_chan_width, cfg->vht_rx_ldpc,
3272 cfg->vht_short_gi_80, cfg->vht_tx_stbc, cfg->vht_rx_stbc,
3273 cfg->vht_txop_ps, cfg->vht_su_bformee, cfg->vht_mu_bformee,
3274 cfg->vht_max_ampdu_len_exp);
3275}
3276#endif /* #ifdef WLAN_FEATURE_11AC */
3277
3278/**
3279 * wma_update_hdd_cfg() - update HDD config
3280 * @wma_handle: wma handle
3281 *
3282 * Return: none
3283 */
3284static void wma_update_hdd_cfg(tp_wma_handle wma_handle)
3285{
3286 struct wma_tgt_cfg tgt_cfg;
3287 void *hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
3288
3289 tgt_cfg.reg_domain = wma_handle->reg_cap.eeprom_rd;
3290 tgt_cfg.eeprom_rd_ext = wma_handle->reg_cap.eeprom_rd_ext;
3291
3292 switch (wma_handle->phy_capability) {
3293 case WMI_11G_CAPABILITY:
3294 case WMI_11NG_CAPABILITY:
3295 tgt_cfg.band_cap = eCSR_BAND_24;
3296 break;
3297 case WMI_11A_CAPABILITY:
3298 case WMI_11NA_CAPABILITY:
3299 case WMI_11AC_CAPABILITY:
3300 tgt_cfg.band_cap = eCSR_BAND_5G;
3301 break;
3302 case WMI_11AG_CAPABILITY:
3303 case WMI_11NAG_CAPABILITY:
3304 default:
3305 tgt_cfg.band_cap = eCSR_BAND_ALL;
3306 }
3307
3308 tgt_cfg.max_intf_count = wma_handle->wlan_resource_config.num_vdevs;
3309
3310 cdf_mem_copy(tgt_cfg.hw_macaddr.bytes, wma_handle->hwaddr,
3311 ATH_MAC_LEN);
3312
3313 wma_update_target_services(wma_handle, &tgt_cfg.services);
3314 wma_update_target_ht_cap(wma_handle, &tgt_cfg.ht_cap);
3315#ifdef WLAN_FEATURE_11AC
3316 wma_update_target_vht_cap(wma_handle, &tgt_cfg.vht_cap);
3317#endif /* #ifdef WLAN_FEATURE_11AC */
3318
3319 tgt_cfg.target_fw_version = wma_handle->target_fw_version;
3320#ifdef WLAN_FEATURE_LPSS
3321 tgt_cfg.lpss_support = wma_handle->lpss_support;
3322#endif /* WLAN_FEATURE_LPSS */
3323 tgt_cfg.ap_arpns_support = wma_handle->ap_arpns_support;
3324 wma_handle->tgt_cfg_update_cb(hdd_ctx, &tgt_cfg);
3325}
3326
3327/**
3328 * wma_setup_wmi_init_msg() - fill wmi init message buffer
3329 * @wma_handle: wma handle
3330 * @ev: ready event fixed params
3331 * @param_buf: redy event TLVs
3332 * @len: buffer length
3333 *
3334 * Return: wmi buffer or NULL for error
3335 */
3336static wmi_buf_t wma_setup_wmi_init_msg(tp_wma_handle wma_handle,
3337 wmi_service_ready_event_fixed_param *ev,
3338 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf,
3339 uint32_t *len)
3340{
3341 wmi_buf_t buf;
3342 wmi_init_cmd_fixed_param *cmd;
3343 wlan_host_mem_req *ev_mem_reqs;
3344 wmi_abi_version my_vers;
3345 int num_whitelist;
3346 uint8_t *buf_ptr;
3347 wmi_resource_config *resource_cfg;
3348 wlan_host_memory_chunk *host_mem_chunks;
3349 uint32_t mem_chunk_len = 0;
3350 uint16_t idx;
3351 uint32_t num_units;
3352
3353 *len = sizeof(*cmd) + sizeof(wmi_resource_config) + WMI_TLV_HDR_SIZE;
3354 mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS);
3355 buf = wmi_buf_alloc(wma_handle->wmi_handle, *len + mem_chunk_len);
3356 if (!buf) {
3357 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
3358 return NULL;
3359 }
3360
3361 ev_mem_reqs = param_buf->mem_reqs;
3362 buf_ptr = (uint8_t *) wmi_buf_data(buf);
3363 cmd = (wmi_init_cmd_fixed_param *) buf_ptr;
3364 resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd));
3365 host_mem_chunks = (wlan_host_memory_chunk *)
3366 (buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)
3367 + WMI_TLV_HDR_SIZE);
3368 WMITLV_SET_HDR(&cmd->tlv_header,
3369 WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param,
3370 WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param));
3371
3372 *resource_cfg = wma_handle->wlan_resource_config;
3373 WMITLV_SET_HDR(&resource_cfg->tlv_header,
3374 WMITLV_TAG_STRUC_wmi_resource_config,
3375 WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config));
3376
3377 /* allocate memory requested by FW */
3378 if (ev->num_mem_reqs > WMI_MAX_MEM_REQS) {
3379 CDF_ASSERT(0);
3380 cdf_nbuf_free(buf);
3381 return NULL;
3382 }
3383
3384 cmd->num_host_mem_chunks = 0;
3385 for (idx = 0; idx < ev->num_mem_reqs; ++idx) {
3386 num_units = ev_mem_reqs[idx].num_units;
3387 if (ev_mem_reqs[idx].num_unit_info & NUM_UNITS_IS_NUM_PEERS) {
3388 /*
3389 * number of units to allocate is number
3390 * of peers, 1 extra for self peer on
3391 * target. this needs to be fied, host
3392 * and target can get out of sync
3393 */
3394 num_units = resource_cfg->num_peers + 1;
3395 }
3396 WMA_LOGD
3397 ("idx %d req %d num_units %d num_unit_info %d unit size %d actual units %d ",
3398 idx, ev_mem_reqs[idx].req_id,
3399 ev_mem_reqs[idx].num_units,
3400 ev_mem_reqs[idx].num_unit_info,
3401 ev_mem_reqs[idx].unit_size, num_units);
3402 wma_alloc_host_mem(wma_handle, ev_mem_reqs[idx].req_id,
3403 num_units, ev_mem_reqs[idx].unit_size);
3404 }
3405 for (idx = 0; idx < wma_handle->num_mem_chunks; ++idx) {
3406 WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header),
3407 WMITLV_TAG_STRUC_wlan_host_memory_chunk,
3408 WMITLV_GET_STRUCT_TLVLEN
3409 (wlan_host_memory_chunk));
3410 host_mem_chunks[idx].ptr = wma_handle->mem_chunks[idx].paddr;
3411 host_mem_chunks[idx].size = wma_handle->mem_chunks[idx].len;
3412 host_mem_chunks[idx].req_id =
3413 wma_handle->mem_chunks[idx].req_id;
3414 WMA_LOGD("chunk %d len %d requested ,ptr 0x%x ",
3415 idx, host_mem_chunks[idx].size,
3416 host_mem_chunks[idx].ptr);
3417 }
3418 cmd->num_host_mem_chunks = wma_handle->num_mem_chunks;
3419 len += (wma_handle->num_mem_chunks * sizeof(wlan_host_memory_chunk));
3420 WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)),
3421 WMITLV_TAG_ARRAY_STRUC,
3422 (sizeof(wlan_host_memory_chunk) *
3423 wma_handle->num_mem_chunks));
3424 cdf_mem_copy(&wma_handle->target_abi_vers,
3425 &param_buf->fixed_param->fw_abi_vers,
3426 sizeof(wmi_abi_version));
3427 num_whitelist = sizeof(version_whitelist) /
3428 sizeof(wmi_whitelist_version_info);
3429 my_vers.abi_version_0 = WMI_ABI_VERSION_0;
3430 my_vers.abi_version_1 = WMI_ABI_VERSION_1;
3431 my_vers.abi_version_ns_0 = WMI_ABI_VERSION_NS_0;
3432 my_vers.abi_version_ns_1 = WMI_ABI_VERSION_NS_1;
3433 my_vers.abi_version_ns_2 = WMI_ABI_VERSION_NS_2;
3434 my_vers.abi_version_ns_3 = WMI_ABI_VERSION_NS_3;
3435
3436 wmi_cmp_and_set_abi_version(num_whitelist, version_whitelist,
3437 &my_vers,
3438 &param_buf->fixed_param->fw_abi_vers,
3439 &cmd->host_abi_vers);
3440
3441 WMA_LOGD("%s: INIT_CMD version: %d, %d, 0x%x, 0x%x, 0x%x, 0x%x",
3442 __func__, WMI_VER_GET_MAJOR(cmd->host_abi_vers.abi_version_0),
3443 WMI_VER_GET_MINOR(cmd->host_abi_vers.abi_version_0),
3444 cmd->host_abi_vers.abi_version_ns_0,
3445 cmd->host_abi_vers.abi_version_ns_1,
3446 cmd->host_abi_vers.abi_version_ns_2,
3447 cmd->host_abi_vers.abi_version_ns_3);
3448
3449 cdf_mem_copy(&wma_handle->final_abi_vers, &cmd->host_abi_vers,
3450 sizeof(wmi_abi_version));
3451 return buf;
3452}
3453
3454/**
3455 * wma_dump_dbs_hw_mode() - Print the DBS HW modes
3456 * @wma_handle: WMA handle
3457 *
3458 * Prints the DBS HW modes sent by the FW as part
3459 * of WMI ready event
3460 *
3461 * Return: None
3462 */
3463void wma_dump_dbs_hw_mode(tp_wma_handle wma_handle)
3464{
3465 uint32_t i, param;
3466
3467 if (!wma_handle) {
3468 WMA_LOGE("%s: Invalid WMA handle", __func__);
3469 return;
3470 }
3471
3472 for (i = 0; i < wma_handle->num_dbs_hw_modes; i++) {
3473 param = wma_handle->hw_mode.hw_mode_list[i];
3474 WMA_LOGA("%s:[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d",
3475 __func__, i,
3476 WMI_DBS_HW_MODE_MAC0_TX_STREAMS_GET(param),
3477 WMI_DBS_HW_MODE_MAC0_RX_STREAMS_GET(param),
3478 WMI_DBS_HW_MODE_MAC0_BANDWIDTH_GET(param));
3479 WMA_LOGA("%s:[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d",
3480 __func__, i,
3481 WMI_DBS_HW_MODE_MAC1_TX_STREAMS_GET(param),
3482 WMI_DBS_HW_MODE_MAC1_RX_STREAMS_GET(param),
3483 WMI_DBS_HW_MODE_MAC1_BANDWIDTH_GET(param));
3484 WMA_LOGA("%s:[%d] DBS:%d Agile DFS:%d", __func__, i,
3485 WMI_DBS_HW_MODE_DBS_MODE_GET(param),
3486 WMI_DBS_HW_MODE_AGILE_DFS_GET(param));
3487 }
3488}
3489
3490/**
3491 * wma_init_scan_fw_mode_config() - Initialize scan/fw mode config
3492 * @wma_handle: WMA handle
3493 *
3494 * Enables all the valid bits of concurrent_scan_config_bits and
3495 * fw_mode_config_bits.
3496 *
3497 * Return: None
3498 */
3499void wma_init_scan_fw_mode_config(tp_wma_handle wma_handle)
3500{
3501 tpAniSirGlobal mac = cds_get_context(CDF_MODULE_ID_PE);
3502
3503 WMA_LOGD("%s: Enter", __func__);
3504
3505 if (!mac) {
3506 WMA_LOGE("%s: Invalid mac handle", __func__);
3507 return;
3508 }
3509
3510 if (!wma_handle) {
3511 WMA_LOGE("%s: Invalid WMA handle", __func__);
3512 return;
3513 }
3514
3515 wma_handle->dual_mac_cfg.cur_scan_config = 0;
3516 wma_handle->dual_mac_cfg.cur_fw_mode_config = 0;
3517
3518 /* If dual mac features are disabled in the INI, we
3519 * need not proceed further
3520 */
3521 if (mac->dual_mac_feature_disable) {
3522 WMA_LOGE("%s: Disabling dual mac capabilities", __func__);
3523 /* All capabilites are initialized to 0. We can return */
3524 goto done;
3525 }
3526
3527 /* The input from FW team is that, by default all the
3528 * bits of concurrent_scan_config_bits and
3529 * FW_mode_config_bits will be enabled. So,
3530 * enabling all the bits here. Adding this API so that
3531 * in the future/variant chipsets, when not all bits are
3532 * enabled, FW can send the initial configuration of the above
3533 * two parameters using the service ready event and they
3534 * can be initialized here.
3535 */
3536 /* Initialize concurrent_scan_config_bits */
3537 WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(
3538 wma_handle->dual_mac_cfg.cur_scan_config, 1);
3539 WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET(
3540 wma_handle->dual_mac_cfg.cur_scan_config, 1);
3541 WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET(
3542 wma_handle->dual_mac_cfg.cur_scan_config, 1);
3543
3544 /* Initialize FW_mode_config_bits */
3545 WMI_DBS_FW_MODE_CFG_DBS_SET(
3546 wma_handle->dual_mac_cfg.cur_fw_mode_config, 1);
3547 WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET(
3548 wma_handle->dual_mac_cfg.cur_fw_mode_config, 1);
3549done:
3550 /* Initialize the previous scan/fw mode config */
3551 wma_handle->dual_mac_cfg.prev_scan_config =
3552 wma_handle->dual_mac_cfg.cur_scan_config;
3553 wma_handle->dual_mac_cfg.prev_fw_mode_config =
3554 wma_handle->dual_mac_cfg.cur_fw_mode_config;
3555
3556 WMA_LOGD("%s: cur_scan_config:%x cur_fw_mode_config:%x",
3557 __func__,
3558 wma_handle->dual_mac_cfg.cur_scan_config,
3559 wma_handle->dual_mac_cfg.cur_fw_mode_config);
3560}
3561
3562/**
3563 * wma_rx_service_ready_event() - event handler to process
3564 * wmi rx sevice ready event.
3565 * @handle: wma handle
3566 * @cmd_param_info: command params info
3567 *
3568 * Return: none
3569 */
3570void wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info)
3571{
3572 wmi_buf_t buf;
3573 uint32_t len;
3574 tp_wma_handle wma_handle = (tp_wma_handle) handle;
3575 struct wma_target_cap target_cap;
3576 WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
3577 wmi_service_ready_event_fixed_param *ev;
3578 int status;
3579 uint32_t *ev_wlan_dbs_hw_mode_list;
3580
3581 WMA_LOGD("%s: Enter", __func__);
3582
3583 param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) cmd_param_info;
3584 if (!(handle && param_buf)) {
3585 WMA_LOGP("%s: Invalid arguments", __func__);
3586 return;
3587 }
3588
3589 ev = param_buf->fixed_param;
3590 if (!ev) {
3591 WMA_LOGP("%s: Invalid buffer", __func__);
3592 return;
3593 }
3594
3595 WMA_LOGA("WMA <-- WMI_SERVICE_READY_EVENTID");
3596
3597 wma_handle->num_dbs_hw_modes = ev->num_dbs_hw_modes;
3598 ev_wlan_dbs_hw_mode_list = param_buf->wlan_dbs_hw_mode_list;
3599 wma_handle->hw_mode.hw_mode_list =
3600 cdf_mem_malloc(sizeof(*wma_handle->hw_mode.hw_mode_list) *
3601 wma_handle->num_dbs_hw_modes);
3602 if (!wma_handle->hw_mode.hw_mode_list) {
3603 WMA_LOGE("%s: Memory allocation failed for DBS", __func__);
3604 /* Continuing with the rest of the processing */
3605 }
3606 cdf_mem_copy(wma_handle->hw_mode.hw_mode_list,
3607 ev_wlan_dbs_hw_mode_list,
3608 (sizeof(*wma_handle->hw_mode.hw_mode_list) *
3609 wma_handle->num_dbs_hw_modes));
3610
3611 wma_dump_dbs_hw_mode(wma_handle);
3612
3613 wma_init_scan_fw_mode_config(wma_handle);
3614
3615 wma_handle->phy_capability = ev->phy_capability;
3616 wma_handle->max_frag_entry = ev->max_frag_entry;
3617 wma_handle->num_rf_chains = ev->num_rf_chains;
3618 cdf_mem_copy(&wma_handle->reg_cap, param_buf->hal_reg_capabilities,
3619 sizeof(HAL_REG_CAPABILITIES));
3620 wma_handle->ht_cap_info = ev->ht_cap_info;
3621#ifdef WLAN_FEATURE_11AC
3622 wma_handle->vht_cap_info = ev->vht_cap_info;
3623 wma_handle->vht_supp_mcs = ev->vht_supp_mcs;
3624#endif /* WLAN_FEATURE_11AC */
3625 wma_handle->num_rf_chains = ev->num_rf_chains;
3626
3627 wma_handle->target_fw_version = ev->fw_build_vers;
3628 ol_tx_set_desc_global_pool_size(ev->num_msdu_desc);
3629 wma_handle->new_hw_mode_index = ev->default_dbs_hw_mode_index;
3630
3631 WMA_LOGD("%s: Firmware default hw mode index : %d",
3632 __func__, ev->default_dbs_hw_mode_index);
3633 WMA_LOGE("%s: Firmware build version : %08x",
3634 __func__, ev->fw_build_vers);
3635
3636 if (ev->hw_bd_id) {
3637 wma_handle->hw_bd_id = ev->hw_bd_id;
3638 cdf_mem_copy(wma_handle->hw_bd_info,
3639 ev->hw_bd_info, sizeof(ev->hw_bd_info));
3640
3641 WMA_LOGE("%s: Board version: %x.%x",
3642 __func__,
3643 wma_handle->hw_bd_info[0], wma_handle->hw_bd_info[1]);
3644 } else {
3645 wma_handle->hw_bd_id = 0;
3646 cdf_mem_zero(wma_handle->hw_bd_info,
3647 sizeof(wma_handle->hw_bd_info));
3648 WMA_LOGE("%s: Board version is unknown!", __func__);
3649 }
3650
3651 /* TODO: Recheck below line to dump service ready event */
3652 /* dbg_print_wmi_service_11ac(ev); */
3653
3654 /* wmi service is ready */
3655 cdf_mem_copy(wma_handle->wmi_service_bitmap,
3656 param_buf->wmi_service_bitmap,
3657 sizeof(wma_handle->wmi_service_bitmap));
3658 /* SWBA event handler for beacon transmission */
3659 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
3660 WMI_HOST_SWBA_EVENTID,
3661 wma_beacon_swba_handler);
3662 if (status) {
3663 WMA_LOGE("Failed to register swba beacon event cb");
3664 return;
3665 }
3666#ifdef WLAN_FEATURE_LPSS
3667 wma_handle->lpss_support =
3668 WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
3669 WMI_SERVICE_LPASS);
3670#endif /* WLAN_FEATURE_LPSS */
3671
3672 /*
3673 * This Service bit is added to check for ARP/NS Offload
3674 * support for LL/HL targets
3675 */
3676 wma_handle->ap_arpns_support =
3677 WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
3678 WMI_SERVICE_AP_ARPNS_OFFLOAD);
3679
3680 if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
3681 WMI_SERVICE_CSA_OFFLOAD)) {
3682 WMA_LOGD("%s: FW support CSA offload capability", __func__);
3683 status =
3684 wmi_unified_register_event_handler(wma_handle->wmi_handle,
3685 WMI_CSA_HANDLING_EVENTID,
3686 wma_csa_offload_handler);
3687 if (status) {
3688 WMA_LOGE("Failed to register CSA offload event cb");
3689 return;
3690 }
3691 }
3692
3693 if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
3694 WMI_SERVICE_MGMT_TX_WMI)) {
3695 WMA_LOGE("Firmware supports management TX over WMI,use WMI interface instead of HTT for management Tx");
3696 status = wmi_desc_pool_init(wma_handle, WMI_DESC_POOL_MAX);
3697 if (status) {
3698 WMA_LOGE("Failed to initialize wmi descriptor pool");
3699 return;
3700 }
3701 /*
3702 * Register Tx completion event handler for MGMT Tx over WMI
3703 * case
3704 */
3705 status = wmi_unified_register_event_handler(
3706 wma_handle->wmi_handle,
3707 WMI_MGMT_TX_COMPLETION_EVENTID,
3708 wma_mgmt_tx_completion_handler);
3709 if (status) {
3710 WMA_LOGE("Failed to register MGMT over WMI completion handler");
3711 return;
3712 }
3713
3714 } else {
3715 WMA_LOGE("FW doesnot support WMI_SERVICE_MGMT_TX_WMI, Use HTT interface for Management Tx");
3716 }
3717#ifdef WLAN_FEATURE_GTK_OFFLOAD
3718 if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
3719 WMI_SERVICE_GTK_OFFLOAD)) {
3720 status =
3721 wmi_unified_register_event_handler(wma_handle->wmi_handle,
3722 WMI_GTK_OFFLOAD_STATUS_EVENTID,
3723 wma_gtk_offload_status_event);
3724 if (status) {
3725 WMA_LOGE("Failed to register GTK offload event cb");
3726 return;
3727 }
3728 }
3729#endif /* WLAN_FEATURE_GTK_OFFLOAD */
3730
3731 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
3732 WMI_P2P_NOA_EVENTID,
3733 wma_p2p_noa_event_handler);
3734 if (status) {
3735 WMA_LOGE("Failed to register WMI_P2P_NOA_EVENTID callback");
3736 return;
3737 }
3738 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
3739 WMI_TBTTOFFSET_UPDATE_EVENTID,
3740 wma_tbttoffset_update_event_handler);
3741 if (status) {
3742 WMA_LOGE
3743 ("Failed to register WMI_TBTTOFFSET_UPDATE_EVENTID callback");
3744 return;
3745 }
3746
3747 /* Initialize the log supported event handler */
3748 status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
3749 WMI_DIAG_EVENT_LOG_SUPPORTED_EVENTID,
3750 wma_log_supported_evt_handler);
3751 if (status != CDF_STATUS_SUCCESS) {
3752 WMA_LOGE("Failed to register log supported event cb");
3753 return;
3754 }
3755
3756 cdf_mem_copy(target_cap.wmi_service_bitmap,
3757 param_buf->wmi_service_bitmap,
3758 sizeof(wma_handle->wmi_service_bitmap));
3759 target_cap.wlan_resource_config = wma_handle->wlan_resource_config;
3760 wma_update_fw_config(wma_handle, &target_cap);
3761 cdf_mem_copy(wma_handle->wmi_service_bitmap,
3762 target_cap.wmi_service_bitmap,
3763 sizeof(wma_handle->wmi_service_bitmap));
3764 wma_handle->wlan_resource_config = target_cap.wlan_resource_config;
3765
3766 buf = wma_setup_wmi_init_msg(wma_handle, ev, param_buf, &len);
3767 if (!buf) {
3768 WMA_LOGE("Failed to setup buffer for wma init command");
3769 return;
3770 }
3771
3772 WMA_LOGA("WMA --> WMI_INIT_CMDID");
3773 status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
3774 WMI_INIT_CMDID);
3775 if (status != EOK) {
3776 WMA_LOGE("Failed to send WMI_INIT_CMDID command");
3777 wmi_buf_free(buf);
3778 return;
3779 }
3780}
3781
3782/**
3783 * wma_rx_service_ready_ext_event() - evt handler for sevice ready ext event.
3784 * @handle: wma handle
3785 * @event: params of the service ready extended event
3786 *
3787 * Return: none
3788 */
3789void wma_rx_service_ready_ext_event(WMA_HANDLE handle, void *event)
3790{
3791 tp_wma_handle wma_handle = (tp_wma_handle) handle;
3792 WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *param_buf;
3793 wmi_service_ready_ext_event_fixed_param *ev;
3794 int status;
3795 CDF_STATUS ret;
3796
3797 WMA_LOGD("%s: Enter", __func__);
3798
3799 if (!wma_handle) {
3800 WMA_LOGP("%s: Invalid WMA handle", __func__);
3801 return;
3802 }
3803
3804 param_buf = (WMI_SERVICE_READY_EXT_EVENTID_param_tlvs *) event;
3805 if (!param_buf) {
3806 WMA_LOGP("%s: Invalid event", __func__);
3807 return;
3808 }
3809
3810 ev = param_buf->fixed_param;
3811 if (!ev) {
3812 WMA_LOGP("%s: Invalid buffer", __func__);
3813 return;
3814 }
3815
3816 WMA_LOGA("WMA <-- WMI_SERVICE_READY_EXT_EVENTID");
3817
3818 if (!wma_handle->saved_wmi_init_cmd.buf) {
3819 WMA_LOGP("Service ready ext event w/o WMI_SERVICE_EXT_MSG!");
3820 return;
3821 }
3822
3823 ret = cdf_event_set(&wma_handle->service_ready_ext_evt);
3824 if (CDF_STATUS_SUCCESS != ret) {
3825 WMA_LOGP("Failed to set service_ready_ext_evt");
3826 return;
3827 }
3828
3829 WMA_LOGA("WMA --> WMI_INIT_CMDID");
3830
3831 status = wmi_unified_cmd_send(wma_handle->wmi_handle,
3832 wma_handle->saved_wmi_init_cmd.buf,
3833 wma_handle->saved_wmi_init_cmd.buf_len,
3834 WMI_INIT_CMDID);
3835 if (status != EOK) {
3836 /* In success case, WMI layer will free after getting copy
3837 * engine TX complete interrupt
3838 */
3839 WMA_LOGE("Failed to send WMI_INIT_CMDID command");
3840 wmi_buf_free(wma_handle->saved_wmi_init_cmd.buf);
3841 }
3842 wma_handle->saved_wmi_init_cmd.buf = NULL;
3843
3844}
3845
3846/**
3847 * wma_rx_ready_event() - event handler to process
3848 * wmi rx ready event.
3849 * @handle: wma handle
3850 * @cmd_param_info: command params info
3851 *
3852 * Return: none
3853 */
3854void wma_rx_ready_event(WMA_HANDLE handle, void *cmd_param_info)
3855{
3856 tp_wma_handle wma_handle = (tp_wma_handle) handle;
3857 WMI_READY_EVENTID_param_tlvs *param_buf = NULL;
3858 wmi_ready_event_fixed_param *ev = NULL;
3859
3860 WMA_LOGD("%s: Enter", __func__);
3861
3862 param_buf = (WMI_READY_EVENTID_param_tlvs *) cmd_param_info;
3863 if (!(wma_handle && param_buf)) {
3864 WMA_LOGP("%s: Invalid arguments", __func__);
3865 CDF_ASSERT(0);
3866 return;
3867 }
3868
3869 WMA_LOGA("WMA <-- WMI_READY_EVENTID");
3870
3871 ev = param_buf->fixed_param;
3872 /* Indicate to the waiting thread that the ready
3873 * event was received */
3874 wma_handle->wmi_ready = true;
3875 wma_handle->wlan_init_status = ev->status;
3876
3877 /*
3878 * We need to check the WMI versions and make sure both
3879 * host and fw are compatible.
3880 */
3881 if (!wmi_versions_are_compatible(&wma_handle->final_abi_vers,
3882 &ev->fw_abi_vers)) {
3883 /*
3884 * Error: Our host version and the given firmware version
3885 * are incompatible.
3886 */
3887 WMA_LOGE("%s: Error: Incompatible WMI version."
3888 "Host: %d,%d,0x%x 0x%x 0x%x 0x%x, FW: %d,%d,0x%x 0x%x 0x%x 0x%x",
3889 __func__,
3890 WMI_VER_GET_MAJOR(wma_handle->final_abi_vers.
3891 abi_version_0),
3892 WMI_VER_GET_MINOR(wma_handle->final_abi_vers.
3893 abi_version_0),
3894 wma_handle->final_abi_vers.abi_version_ns_0,
3895 wma_handle->final_abi_vers.abi_version_ns_1,
3896 wma_handle->final_abi_vers.abi_version_ns_2,
3897 wma_handle->final_abi_vers.abi_version_ns_3,
3898 WMI_VER_GET_MAJOR(ev->fw_abi_vers.abi_version_0),
3899 WMI_VER_GET_MINOR(ev->fw_abi_vers.abi_version_0),
3900 ev->fw_abi_vers.abi_version_ns_0,
3901 ev->fw_abi_vers.abi_version_ns_1,
3902 ev->fw_abi_vers.abi_version_ns_2,
3903 ev->fw_abi_vers.abi_version_ns_3);
3904 if (wma_handle->wlan_init_status == WLAN_INIT_STATUS_SUCCESS) {
3905 /* Failed this connection to FW */
3906 wma_handle->wlan_init_status =
3907 WLAN_INIT_STATUS_GEN_FAILED;
3908 }
3909 }
3910 cdf_mem_copy(&wma_handle->final_abi_vers, &ev->fw_abi_vers,
3911 sizeof(wmi_abi_version));
3912 cdf_mem_copy(&wma_handle->target_abi_vers, &ev->fw_abi_vers,
3913 sizeof(wmi_abi_version));
3914
3915 /* copy the mac addr */
3916 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, wma_handle->myaddr);
3917 WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->mac_addr, wma_handle->hwaddr);
3918
3919 wma_update_hdd_cfg(wma_handle);
3920
3921 cdf_event_set(&wma_handle->wma_ready_event);
3922
3923 WMA_LOGD("Exit");
3924}
3925
3926/**
3927 * wma_setneedshutdown() - setting wma needshutdown flag
3928 * @cds_ctx: cds context
3929 *
3930 * Return: none
3931 */
3932void wma_setneedshutdown(void *cds_ctx)
3933{
3934 tp_wma_handle wma_handle;
3935
3936 WMA_LOGD("%s: Enter", __func__);
3937
3938 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
3939
3940 if (NULL == wma_handle) {
3941 WMA_LOGP("%s: Invalid arguments", __func__);
3942 CDF_ASSERT(0);
3943 return;
3944 }
3945
3946 wma_handle->needShutdown = true;
3947 WMA_LOGD("%s: Exit", __func__);
3948}
3949
3950/**
3951 * wma_needshutdown() - Is wma needs shutdown?
3952 * @cds_ctx: cds context
3953 *
3954 * Return: returns true/false
3955 */
3956bool wma_needshutdown(void *cds_ctx)
3957{
3958 tp_wma_handle wma_handle;
3959
3960 WMA_LOGD("%s: Enter", __func__);
3961
3962 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
3963
3964 if (NULL == wma_handle) {
3965 WMA_LOGP("%s: Invalid arguments", __func__);
3966 CDF_ASSERT(0);
3967 return false;
3968 }
3969
3970 WMA_LOGD("%s: Exit", __func__);
3971 return wma_handle->needShutdown;
3972}
3973
3974/**
3975 * wma_wait_for_ready_event() - wait for wma ready event
3976 * @handle: wma handle
3977 *
3978 * Return: 0 for success or CDF error
3979 */
3980CDF_STATUS wma_wait_for_ready_event(WMA_HANDLE handle)
3981{
3982 tp_wma_handle wma_handle = (tp_wma_handle) handle;
3983 CDF_STATUS cdf_status;
3984
3985 /* wait until WMI_READY_EVENTID received from FW */
3986 cdf_status = cdf_wait_single_event(&(wma_handle->wma_ready_event),
3987 WMA_READY_EVENTID_TIMEOUT);
3988
3989 if (CDF_STATUS_SUCCESS != cdf_status) {
3990 WMA_LOGP("%s: Timeout waiting for ready event from FW",
3991 __func__);
3992 cdf_status = CDF_STATUS_E_FAILURE;
3993 }
3994 return cdf_status;
3995}
3996
3997/**
3998 * wma_set_ppsconfig() - set pps config in fw
3999 * @vdev_id: vdev id
4000 * @pps_param: pps params
4001 * @val : param value
4002 *
4003 * Return: 0 for success or CDF error
4004 */
4005CDF_STATUS wma_set_ppsconfig(uint8_t vdev_id, uint16_t pps_param,
4006 int val)
4007{
4008 tp_wma_handle wma = cds_get_context(CDF_MODULE_ID_WMA);
4009 int ret = -EIO;
4010 uint32_t pps_val;
4011
4012 if (NULL == wma) {
4013 WMA_LOGE("%s: Failed to get wma", __func__);
4014 return CDF_STATUS_E_INVAL;
4015 }
4016
4017 switch (pps_param) {
4018 case WMA_VHT_PPS_PAID_MATCH:
4019 pps_val = ((val << 31) & 0xffff0000) |
4020 (PKT_PWR_SAVE_PAID_MATCH & 0xffff);
4021 goto pkt_pwr_save_config;
4022 case WMA_VHT_PPS_GID_MATCH:
4023 pps_val = ((val << 31) & 0xffff0000) |
4024 (PKT_PWR_SAVE_GID_MATCH & 0xffff);
4025 goto pkt_pwr_save_config;
4026 case WMA_VHT_PPS_DELIM_CRC_FAIL:
4027 pps_val = ((val << 31) & 0xffff0000) |
4028 (PKT_PWR_SAVE_DELIM_CRC_FAIL & 0xffff);
4029 goto pkt_pwr_save_config;
4030
4031 /* Enable the code below as and when the functionality
4032 * is supported/added in host.
4033 */
4034#ifdef NOT_YET
4035 case WMA_VHT_PPS_EARLY_TIM_CLEAR:
4036 pps_val = ((val << 31) & 0xffff0000) |
4037 (PKT_PWR_SAVE_EARLY_TIM_CLEAR & 0xffff);
4038 goto pkt_pwr_save_config;
4039 case WMA_VHT_PPS_EARLY_DTIM_CLEAR:
4040 pps_val = ((val << 31) & 0xffff0000) |
4041 (PKT_PWR_SAVE_EARLY_DTIM_CLEAR & 0xffff);
4042 goto pkt_pwr_save_config;
4043 case WMA_VHT_PPS_EOF_PAD_DELIM:
4044 pps_val = ((val << 31) & 0xffff0000) |
4045 (PKT_PWR_SAVE_EOF_PAD_DELIM & 0xffff);
4046 goto pkt_pwr_save_config;
4047 case WMA_VHT_PPS_MACADDR_MISMATCH:
4048 pps_val = ((val << 31) & 0xffff0000) |
4049 (PKT_PWR_SAVE_MACADDR_MISMATCH & 0xffff);
4050 goto pkt_pwr_save_config;
4051 case WMA_VHT_PPS_GID_NSTS_ZERO:
4052 pps_val = ((val << 31) & 0xffff0000) |
4053 (PKT_PWR_SAVE_GID_NSTS_ZERO & 0xffff);
4054 goto pkt_pwr_save_config;
4055 case WMA_VHT_PPS_RSSI_CHECK:
4056 pps_val = ((val << 31) & 0xffff0000) |
4057 (PKT_PWR_SAVE_RSSI_CHECK & 0xffff);
4058 goto pkt_pwr_save_config;
4059#endif /* NOT_YET */
4060pkt_pwr_save_config:
4061 WMA_LOGD("vdev_id:%d val:0x%x pps_val:0x%x", vdev_id,
4062 val, pps_val);
4063 ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id,
4064 WMI_VDEV_PARAM_PACKET_POWERSAVE,
4065 pps_val);
4066 break;
4067 default:
4068 WMA_LOGE("%s:INVALID PPS CONFIG", __func__);
4069 }
4070
4071 return (ret) ? CDF_STATUS_E_FAILURE : CDF_STATUS_SUCCESS;
4072}
4073
4074/**
4075 * wma_process_set_mas() - Function to enable/disable MAS
4076 * @wma: Pointer to WMA handle
4077 * @mas_val: 1-Enable MAS, 0-Disable MAS
4078 *
4079 * This function enables/disables the MAS value
4080 *
4081 * Return: CDF_SUCCESS for success otherwise failure
4082 */
4083CDF_STATUS wma_process_set_mas(tp_wma_handle wma,
4084 uint32_t *mas_val)
4085{
4086 uint32_t val;
4087
4088 if (NULL == wma || NULL == mas_val) {
4089 WMA_LOGE("%s: Invalid input to enable/disable MAS", __func__);
4090 return CDF_STATUS_E_FAILURE;
4091 }
4092
4093 val = (*mas_val);
4094
4095 if (CDF_STATUS_SUCCESS !=
4096 wma_set_enable_disable_mcc_adaptive_scheduler(val)) {
4097 WMA_LOGE("%s: Unable to enable/disable MAS", __func__);
4098 return CDF_STATUS_E_FAILURE;
4099 } else {
4100 WMA_LOGE("%s: Value is %d", __func__, val);
4101 }
4102
4103 return CDF_STATUS_SUCCESS;
4104}
4105
4106/**
4107 * wma_process_set_miracast() - Function to set miracast value in WMA
4108 * @wma: Pointer to WMA handle
4109 * @miracast_val: 0-Disabled,1-Source,2-Sink
4110 *
4111 * This function stores the miracast value in WMA
4112 *
4113 * Return: CDF_SUCCESS for success otherwise failure
4114 *
4115 */
4116CDF_STATUS wma_process_set_miracast(tp_wma_handle wma, uint32_t *miracast_val)
4117{
4118 if (NULL == wma || NULL == miracast_val) {
4119 WMA_LOGE("%s: Invalid input to store miracast value", __func__);
4120 return CDF_STATUS_E_FAILURE;
4121 }
4122
4123 wma->miracast_value = *miracast_val;
4124 WMA_LOGE("%s: Miracast value is %d", __func__, wma->miracast_value);
4125
4126 return CDF_STATUS_SUCCESS;
4127}
4128
4129/**
4130 * wma_config_stats_factor() - Function to configure stats avg. factor
4131 * @wma: pointer to WMA handle
4132 * @avg_factor: stats. avg. factor passed down by userspace
4133 *
4134 * This function configures the avg. stats value in firmware
4135 *
4136 * Return: CDF_STATUS_SUCCESS for success otherwise failure
4137 *
4138 */
4139static CDF_STATUS wma_config_stats_factor(tp_wma_handle wma,
4140 struct sir_stats_avg_factor *avg_factor)
4141{
4142 int ret;
4143
4144 if (NULL == wma || NULL == avg_factor) {
4145 WMA_LOGE("%s: Invalid input of stats avg factor", __func__);
4146 return CDF_STATUS_E_FAILURE;
4147 }
4148
4149 ret = wmi_unified_vdev_set_param_send(wma->wmi_handle,
4150 avg_factor->vdev_id,
4151 WMI_VDEV_PARAM_STATS_AVG_FACTOR,
4152 avg_factor->stats_avg_factor);
4153 if (ret) {
4154 WMA_LOGE(" failed to set avg_factor for vdev_id %d",
4155 avg_factor->vdev_id);
4156 }
4157
4158 WMA_LOGD("%s: Set stats_avg_factor %d for vdev_id %d", __func__,
4159 avg_factor->stats_avg_factor, avg_factor->vdev_id);
4160
4161 return ret;
4162}
4163
4164/**
4165 * wma_config_guard_time() - Function to set guard time in firmware
4166 * @wma: pointer to WMA handle
4167 * @guard_time: guard time passed down by userspace
4168 *
4169 * This function configures the guard time in firmware
4170 *
4171 * Return: CDF_STATUS_SUCCESS for success otherwise failure
4172 *
4173 */
4174static CDF_STATUS wma_config_guard_time(tp_wma_handle wma,
4175 struct sir_guard_time_request *guard_time)
4176{
4177 int ret;
4178
4179 if (NULL == wma || NULL == guard_time) {
4180 WMA_LOGE("%s: Invalid input of guard time", __func__);
4181 return CDF_STATUS_E_FAILURE;
4182 }
4183
4184 ret = wmi_unified_vdev_set_param_send(wma->wmi_handle,
4185 guard_time->vdev_id,
4186 WMI_VDEV_PARAM_RX_LEAK_WINDOW,
4187 guard_time->guard_time);
4188 if (ret) {
4189 WMA_LOGE(" failed to set guard time for vdev_id %d",
4190 guard_time->vdev_id);
4191 }
4192
4193 WMA_LOGD("Set guard time %d for vdev_id %d",
4194 guard_time->guard_time, guard_time->vdev_id);
4195
4196 return ret;
4197}
4198
4199/**
4200 * wma_enable_specific_fw_logs() - Start/Stop logging of diag event/log id
4201 * @wma_handle: WMA handle
4202 * @start_log: Start logging related parameters
4203 *
4204 * Send the command to the FW based on which specific logging of diag
4205 * event/log id can be started/stopped
4206 *
4207 * Return: None
4208 */
4209void wma_enable_specific_fw_logs(tp_wma_handle wma_handle,
4210 struct sir_wifi_start_log *start_log)
4211{
4212 wmi_diag_event_log_config_fixed_param *cmd;
4213 wmi_buf_t buf;
4214 uint8_t *buf_ptr;
4215 uint32_t len, count, log_level, i;
4216 uint32_t *cmd_args;
4217 uint32_t total_len;
4218 count = 0;
4219
4220 if (!start_log) {
4221 WMA_LOGE("%s: start_log pointer is NULL", __func__);
4222 return;
4223 }
4224 if (!wma_handle) {
4225 WMA_LOGE("%s: Invalid wma handle", __func__);
4226 return;
4227 }
4228
4229 if (!((start_log->ring_id == RING_ID_CONNECTIVITY) ||
4230 (start_log->ring_id == RING_ID_FIRMWARE_DEBUG))) {
4231 WMA_LOGD("%s: Not connectivity or fw debug ring: %d",
4232 __func__, start_log->ring_id);
4233 return;
4234 }
4235
4236 if (!wma_handle->events_logs_list) {
4237 WMA_LOGE("%s: Not received event/log list from FW, yet",
4238 __func__);
4239 return;
4240 }
4241
4242 /* total_len stores the number of events where BITS 17 and 18 are set.
4243 * i.e., events of high frequency (17) and for extended debugging (18)
4244 */
4245 total_len = 0;
4246 for (i = 0; i < wma_handle->num_of_diag_events_logs; i++) {
4247 if ((WMI_DIAG_FREQUENCY_GET(wma_handle->events_logs_list[i])) &&
4248 (WMI_DIAG_EXT_FEATURE_GET(wma_handle->events_logs_list[i])))
4249 total_len++;
4250 }
4251
4252 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
4253 (total_len * sizeof(uint32_t));
4254
4255 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
4256 if (!buf) {
4257 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
4258 return;
4259 }
4260 cmd = (wmi_diag_event_log_config_fixed_param *) wmi_buf_data(buf);
4261 buf_ptr = (uint8_t *) cmd;
4262
4263 WMITLV_SET_HDR(&cmd->tlv_header,
4264 WMITLV_TAG_STRUC_wmi_diag_event_log_config_fixed_param,
4265 WMITLV_GET_STRUCT_TLVLEN(
4266 wmi_diag_event_log_config_fixed_param));
4267
4268 cmd->num_of_diag_events_logs = total_len;
4269
4270 buf_ptr += sizeof(wmi_diag_event_log_config_fixed_param);
4271
4272 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
4273 (total_len * sizeof(uint32_t)));
4274
4275 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
4276
4277 if (start_log->verbose_level >= LOG_LEVEL_ACTIVE)
4278 log_level = 1;
4279 else
4280 log_level = 0;
4281
4282 WMA_LOGD("%s: Length:%d, Log_level:%d", __func__, total_len, log_level);
4283 for (i = 0; i < wma_handle->num_of_diag_events_logs; i++) {
4284 uint32_t val = wma_handle->events_logs_list[i];
4285 if ((WMI_DIAG_FREQUENCY_GET(val)) &&
4286 (WMI_DIAG_EXT_FEATURE_GET(val))) {
4287
4288 WMI_DIAG_ID_SET(cmd_args[count],
4289 WMI_DIAG_ID_GET(val));
4290 WMI_DIAG_TYPE_SET(cmd_args[count],
4291 WMI_DIAG_TYPE_GET(val));
4292 WMI_DIAG_ID_ENABLED_DISABLED_SET(cmd_args[count],
4293 log_level);
4294 WMA_LOGD("%s: Idx:%d, val:%x", __func__, i, val);
4295 count++;
4296 }
4297 }
4298
4299 if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
4300 WMI_DIAG_EVENT_LOG_CONFIG_CMDID)) {
4301 WMA_LOGE("%s: WMI_DIAG_EVENT_LOG_CONFIG_CMDID failed",
4302 __func__);
4303 wmi_buf_free(buf);
4304 }
4305 return;
4306}
4307
4308#if !defined(REMOVE_PKT_LOG)
4309/**
4310 * wma_set_wifi_start_packet_stats() - Start/stop packet stats
4311 * @wma_handle: WMA handle
4312 * @start_log: Struture containing the start wifi logger params
4313 *
4314 * This function is used to send the WMA commands to start/stop logging
4315 * of per packet statistics
4316 *
4317 * Return: None
4318 *
4319 */
4320void wma_set_wifi_start_packet_stats(void *wma_handle,
4321 struct sir_wifi_start_log *start_log)
4322{
4323 struct ol_softc *scn;
4324 uint32_t log_state;
4325
4326 if (!start_log) {
4327 WMA_LOGE("%s: start_log pointer is NULL", __func__);
4328 return;
4329 }
4330 if (!wma_handle) {
4331 WMA_LOGE("%s: Invalid wma handle", __func__);
4332 return;
4333 }
4334
4335 /* No need to register for ring IDs other than packet stats */
4336 if (start_log->ring_id != RING_ID_PER_PACKET_STATS) {
4337 WMA_LOGI("%s: Ring id is not for per packet stats: %d",
4338 __func__, start_log->ring_id);
4339 return;
4340 }
4341
4342 scn = cds_get_context(CDF_MODULE_ID_HIF);
4343
4344 log_state = ATH_PKTLOG_ANI | ATH_PKTLOG_RCUPDATE | ATH_PKTLOG_RCFIND |
4345 ATH_PKTLOG_RX | ATH_PKTLOG_TX | ATH_PKTLOG_TEXT;
4346
4347 if (start_log->verbose_level == WLAN_LOG_LEVEL_ACTIVE) {
4348 pktlog_enable(scn, log_state);
4349 WMA_LOGI("%s: Enabling per packet stats", __func__);
4350 } else {
4351 pktlog_enable(scn, 0);
4352 WMA_LOGI("%s: Disabling per packet stats", __func__);
4353 }
4354}
4355#endif
4356
4357/**
4358 * wma_send_flush_logs_to_fw() - Send log flush command to FW
4359 * @wma_handle: WMI handle
4360 *
4361 * This function is used to send the flush command to the FW,
4362 * that will flush the fw logs that are residue in the FW
4363 *
4364 * Return: None
4365 */
4366void wma_send_flush_logs_to_fw(tp_wma_handle wma_handle)
4367{
4368 CDF_STATUS status;
4369 wmi_debug_mesg_flush_fixed_param *cmd;
4370 wmi_buf_t buf;
4371 int len = sizeof(*cmd);
4372 int ret;
4373
4374 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
4375 if (!buf) {
4376 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
4377 return;
4378 }
4379
4380 cmd = (wmi_debug_mesg_flush_fixed_param *) wmi_buf_data(buf);
4381 WMITLV_SET_HDR(&cmd->tlv_header,
4382 WMITLV_TAG_STRUC_wmi_debug_mesg_flush_fixed_param,
4383 WMITLV_GET_STRUCT_TLVLEN(
4384 wmi_debug_mesg_flush_fixed_param));
4385 cmd->reserved0 = 0;
4386
4387 ret = wmi_unified_cmd_send(wma_handle->wmi_handle,
4388 buf,
4389 len,
4390 WMI_DEBUG_MESG_FLUSH_CMDID);
4391 if (ret != EOK) {
4392 WMA_LOGE("Failed to send WMI_DEBUG_MESG_FLUSH_CMDID");
4393 wmi_buf_free(buf);
4394 return;
4395 }
4396 WMA_LOGI("Sent WMI_DEBUG_MESG_FLUSH_CMDID to FW");
4397
4398 status = cdf_mc_timer_start(&wma_handle->log_completion_timer,
4399 WMA_LOG_COMPLETION_TIMER);
4400 if (status != CDF_STATUS_SUCCESS)
4401 WMA_LOGE("Failed to start the log completion timer");
4402}
4403
4404/**
4405 * wma_mc_process_msg() - process wma messages and call appropriate function.
4406 * @cds_context: cds context
4407 * @msg: message
4408 *
4409 * Return: CDF_SUCCESS for success otherwise failure
4410 */
4411CDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
4412{
4413 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
4414 tp_wma_handle wma_handle;
4415 ol_txrx_vdev_handle txrx_vdev_handle = NULL;
4416 extern uint8_t *mac_trace_get_wma_msg_string(uint16_t wmaMsg);
4417
4418 WMA_LOGI("%s: Enter", __func__);
4419 if (NULL == msg) {
4420 WMA_LOGE("msg is NULL");
4421 CDF_ASSERT(0);
4422 cdf_status = CDF_STATUS_E_INVAL;
4423 goto end;
4424 }
4425
4426 WMA_LOGD("msg->type = %x %s", msg->type,
4427 mac_trace_get_wma_msg_string(msg->type));
4428
4429 wma_handle = cds_get_context(CDF_MODULE_ID_WMA);
4430
4431 if (NULL == wma_handle) {
4432 WMA_LOGP("%s: wma_handle is NULL", __func__);
4433 CDF_ASSERT(0);
4434 cdf_mem_free(msg->bodyptr);
4435 cdf_status = CDF_STATUS_E_INVAL;
4436 goto end;
4437 }
4438
4439 switch (msg->type) {
4440
4441 /* Message posted by wmi for all control path related
4442 * FW events to serialize through mc_thread.
4443 */
4444 case WMA_PROCESS_FW_EVENT:
4445 wma_process_fw_event(wma_handle,
4446 (wma_process_fw_event_params *) msg->bodyptr);
4447 cdf_mem_free(msg->bodyptr);
4448 break;
4449
4450#ifdef FEATURE_WLAN_ESE
4451 case WMA_TSM_STATS_REQ:
4452 WMA_LOGA("McThread: WMA_TSM_STATS_REQ");
4453 wma_process_tsm_stats_req(wma_handle, (void *)msg->bodyptr);
4454 break;
4455#endif /* FEATURE_WLAN_ESE */
4456 case WNI_CFG_DNLD_REQ:
4457 WMA_LOGA("McThread: WNI_CFG_DNLD_REQ");
4458 cdf_status = wma_wni_cfg_dnld(wma_handle);
4459 if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
4460 cds_wma_complete_cback(cds_context);
4461 } else {
4462 WMA_LOGD("config download failure");
4463 }
4464 break;
4465 case WMA_ADD_STA_SELF_REQ:
4466 txrx_vdev_handle =
4467 wma_vdev_attach(wma_handle,
4468 (struct add_sta_self_params *) msg->
4469 bodyptr, 1);
4470 if (!txrx_vdev_handle) {
4471 WMA_LOGE("Failed to attach vdev");
4472 } else {
4473 /* Register with TxRx Module for Data Ack Complete Cb */
4474 ol_txrx_data_tx_cb_set(txrx_vdev_handle,
4475 wma_data_tx_ack_comp_hdlr,
4476 wma_handle);
4477 }
4478 break;
4479 case WMA_DEL_STA_SELF_REQ:
4480 wma_vdev_detach(wma_handle,
4481 (struct del_sta_self_params *) msg->bodyptr, 1);
4482 break;
4483 case WMA_START_SCAN_OFFLOAD_REQ:
4484 wma_start_scan(wma_handle, msg->bodyptr, msg->type);
4485 cdf_mem_free(msg->bodyptr);
4486 break;
4487 case WMA_STOP_SCAN_OFFLOAD_REQ:
4488 wma_stop_scan(wma_handle, msg->bodyptr);
4489 cdf_mem_free(msg->bodyptr);
4490 break;
4491 case WMA_UPDATE_CHAN_LIST_REQ:
4492 wma_update_channel_list(wma_handle,
4493 (tSirUpdateChanList *) msg->bodyptr);
4494 cdf_mem_free(msg->bodyptr);
4495 break;
4496 case WMA_SET_LINK_STATE:
4497 wma_set_linkstate(wma_handle, (tpLinkStateParams) msg->bodyptr);
4498 break;
4499 case WMA_CHNL_SWITCH_REQ:
4500 wma_set_channel(wma_handle,
4501 (tpSwitchChannelParams) msg->bodyptr);
4502 break;
4503 case WMA_ADD_BSS_REQ:
4504 wma_add_bss(wma_handle, (tpAddBssParams) msg->bodyptr);
4505 break;
4506 case WMA_ADD_STA_REQ:
4507 wma_add_sta(wma_handle, (tpAddStaParams) msg->bodyptr);
4508 break;
4509 case WMA_SET_BSSKEY_REQ:
4510 wma_set_bsskey(wma_handle, (tpSetBssKeyParams) msg->bodyptr);
4511 break;
4512 case WMA_SET_STAKEY_REQ:
4513 wma_set_stakey(wma_handle, (tpSetStaKeyParams) msg->bodyptr);
4514 break;
4515 case WMA_DELETE_STA_REQ:
4516 wma_delete_sta(wma_handle, (tpDeleteStaParams) msg->bodyptr);
4517 break;
4518 case WMA_DELETE_BSS_REQ:
4519 wma_delete_bss(wma_handle, (tpDeleteBssParams) msg->bodyptr);
4520 break;
4521 case WMA_UPDATE_EDCA_PROFILE_IND:
4522 wma_process_update_edca_param_req(wma_handle,
4523 (tEdcaParams *) msg->bodyptr);
4524 cdf_mem_free(msg->bodyptr);
4525 break;
4526 case WMA_SEND_BEACON_REQ:
4527 wma_send_beacon(wma_handle, (tpSendbeaconParams) msg->bodyptr);
4528 cdf_mem_free(msg->bodyptr);
4529 break;
4530 case WMA_SEND_PROBE_RSP_TMPL:
4531 wma_send_probe_rsp_tmpl(wma_handle,
4532 (tpSendProbeRespParams) msg->bodyptr);
4533 cdf_mem_free(msg->bodyptr);
4534 break;
4535 case WMA_CLI_SET_CMD:
4536 wma_process_cli_set_cmd(wma_handle,
4537 (wma_cli_set_cmd_t *) msg->bodyptr);
4538 cdf_mem_free(msg->bodyptr);
4539 break;
4540#if !defined(REMOVE_PKT_LOG)
4541 case WMA_PKTLOG_ENABLE_REQ:
4542 wma_pktlog_wmi_send_cmd(wma_handle,
4543 (struct ath_pktlog_wmi_params *)msg->bodyptr);
4544 cdf_mem_free(msg->bodyptr);
4545 break;
4546#endif /* REMOVE_PKT_LOG */
4547#if defined(QCA_WIFI_FTM)
4548 case WMA_FTM_CMD_REQ:
4549 wma_process_ftm_command(wma_handle,
4550 (struct ar6k_testmode_cmd_data *)msg->bodyptr);
4551 break;
4552#endif /* QCA_WIFI_FTM */
4553 case WMA_ENTER_PS_REQ:
4554 wma_enable_sta_ps_mode(wma_handle,
4555 (tpEnablePsParams) msg->bodyptr);
4556 cdf_mem_free(msg->bodyptr);
4557 break;
4558 case WMA_EXIT_PS_REQ:
4559 wma_disable_sta_ps_mode(wma_handle,
4560 (tpDisablePsParams) msg->bodyptr);
4561 cdf_mem_free(msg->bodyptr);
4562 break;
4563 case WMA_ENABLE_UAPSD_REQ:
4564 wma_enable_uapsd_mode(wma_handle,
4565 (tpEnableUapsdParams) msg->bodyptr);
4566 cdf_mem_free(msg->bodyptr);
4567 break;
4568 case WMA_DISABLE_UAPSD_REQ:
4569 wma_disable_uapsd_mode(wma_handle,
4570 (tpDisableUapsdParams) msg->bodyptr);
4571 cdf_mem_free(msg->bodyptr);
4572 break;
4573 case WMA_SET_TX_POWER_REQ:
4574 wma_set_tx_power(wma_handle, (tpMaxTxPowerParams) msg->bodyptr);
4575 break;
4576 case WMA_SET_MAX_TX_POWER_REQ:
4577 wma_set_max_tx_power(wma_handle,
4578 (tpMaxTxPowerParams) msg->bodyptr);
4579 break;
4580 case WMA_SET_KEEP_ALIVE:
4581 wma_set_keepalive_req(wma_handle,
4582 (tSirKeepAliveReq *) msg->bodyptr);
4583 break;
4584#ifdef FEATURE_WLAN_SCAN_PNO
4585 case WMA_SET_PNO_REQ:
4586 wma_config_pno(wma_handle, (tpSirPNOScanReq) msg->bodyptr);
4587 break;
4588
4589 case WMA_SME_SCAN_CACHE_UPDATED:
4590 wma_scan_cache_updated_ind(wma_handle, msg->bodyval);
4591 break;
4592#endif /* FEATURE_WLAN_SCAN_PNO */
4593#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4594 case WMA_SET_PLM_REQ:
4595 wma_config_plm(wma_handle, (tpSirPlmReq) msg->bodyptr);
4596 break;
4597#endif
4598 case WMA_GET_STATISTICS_REQ:
4599 wma_get_stats_req(wma_handle,
4600 (tAniGetPEStatsReq *) msg->bodyptr);
4601 break;
4602
4603 case WMA_CONFIG_PARAM_UPDATE_REQ:
4604 wma_update_cfg_params(wma_handle, (tSirMsgQ *) msg);
4605 break;
4606
4607 case WMA_UPDATE_OP_MODE:
4608 wma_process_update_opmode(wma_handle,
4609 (tUpdateVHTOpMode *) msg->bodyptr);
4610 cdf_mem_free(msg->bodyptr);
4611 break;
4612 case WMA_UPDATE_RX_NSS:
4613 wma_process_update_rx_nss(wma_handle,
4614 (tUpdateRxNss *) msg->bodyptr);
4615 cdf_mem_free(msg->bodyptr);
4616 break;
4617#ifdef WLAN_FEATURE_11AC
4618 case WMA_UPDATE_MEMBERSHIP:
4619 wma_process_update_membership(wma_handle,
4620 (tUpdateMembership *) msg->bodyptr);
4621 break;
4622 case WMA_UPDATE_USERPOS:
4623 wma_process_update_userpos(wma_handle,
4624 (tUpdateUserPos *) msg->bodyptr);
4625 break;
4626#endif /* WLAN_FEATURE_11AC */
4627 case WMA_UPDATE_BEACON_IND:
4628 wma_process_update_beacon_params(wma_handle,
4629 (tUpdateBeaconParams *) msg->bodyptr);
4630 cdf_mem_free(msg->bodyptr);
4631 break;
4632
4633 case WMA_ADD_TS_REQ:
4634 wma_add_ts_req(wma_handle, (tAddTsParams *) msg->bodyptr);
4635 break;
4636
4637 case WMA_DEL_TS_REQ:
4638 wma_del_ts_req(wma_handle, (tDelTsParams *) msg->bodyptr);
4639 break;
4640
4641 case WMA_AGGR_QOS_REQ:
4642 wma_aggr_qos_req(wma_handle, (tAggrAddTsParams *) msg->bodyptr);
4643 break;
4644
4645 case WMA_RECEIVE_FILTER_SET_FILTER_REQ:
4646 wma_process_receive_filter_set_filter_req(wma_handle,
4647 (tSirRcvPktFilterCfgType *) msg->bodyptr);
4648 cdf_mem_free(msg->bodyptr);
4649 break;
4650
4651 case WMA_RECEIVE_FILTER_CLEAR_FILTER_REQ:
4652 wma_process_receive_filter_clear_filter_req(wma_handle,
4653 (tSirRcvFltPktClearParam *) msg->bodyptr);
4654 cdf_mem_free(msg->bodyptr);
4655 break;
4656
4657 case WMA_WOW_ADD_PTRN:
4658 wma_wow_add_pattern(wma_handle,
4659 (struct wow_add_pattern *) msg->bodyptr);
4660 cdf_mem_free(msg->bodyptr);
4661 break;
4662 case WMA_WOW_DEL_PTRN:
4663 wma_wow_delete_user_pattern(wma_handle,
4664 (struct wow_delete_pattern *) msg->bodyptr);
4665 cdf_mem_free(msg->bodyptr);
4666 break;
4667 case WMA_WOWL_ENTER_REQ:
4668 wma_wow_enter(wma_handle,
4669 (tpSirHalWowlEnterParams) msg->bodyptr);
4670 break;
4671 case WMA_WOWL_EXIT_REQ:
4672 wma_wow_exit(wma_handle, (tpSirHalWowlExitParams) msg->bodyptr);
4673 break;
4674 case WMA_WLAN_SUSPEND_IND:
4675 wma_suspend_req(wma_handle,
4676 (tpSirWlanSuspendParam) msg->bodyptr);
4677 break;
4678 case WMA_8023_MULTICAST_LIST_REQ:
4679 wma_process_mcbc_set_filter_req(wma_handle,
4680 (tpSirRcvFltMcAddrList) msg->bodyptr);
4681 cdf_mem_free(msg->bodyptr);
4682 break;
4683#ifdef WLAN_FEATURE_GTK_OFFLOAD
4684 case WMA_GTK_OFFLOAD_REQ:
4685 wma_process_gtk_offload_req(wma_handle,
4686 (tpSirGtkOffloadParams) msg->bodyptr);
4687 break;
4688
4689 case WMA_GTK_OFFLOAD_GETINFO_REQ:
4690 wma_process_gtk_offload_getinfo_req(wma_handle,
4691 (tpSirGtkOffloadGetInfoRspParams)msg->bodyptr);
4692 break;
4693#endif /* WLAN_FEATURE_GTK_OFFLOAD */
4694#ifdef FEATURE_OEM_DATA_SUPPORT
4695 case WMA_START_OEM_DATA_REQ:
4696 wma_start_oem_data_req(wma_handle,
4697 (tStartOemDataReq *) msg->bodyptr);
4698 break;
4699#endif /* FEATURE_OEM_DATA_SUPPORT */
4700 case WMA_SET_HOST_OFFLOAD:
4701 wma_enable_arp_ns_offload(wma_handle,
4702 (tpSirHostOffloadReq) msg->bodyptr,
4703 true);
4704 break;
4705#ifdef WLAN_NS_OFFLOAD
4706 case WMA_SET_NS_OFFLOAD:
4707 wma_enable_arp_ns_offload(wma_handle,
4708 (tpSirHostOffloadReq) msg->bodyptr,
4709 false);
4710 break;
4711#endif /*WLAN_NS_OFFLOAD */
4712 case WMA_ROAM_SCAN_OFFLOAD_REQ:
4713 /*
4714 * Main entry point or roaming directives from CSR.
4715 */
4716 wma_process_roam_scan_req(wma_handle,
4717 (tSirRoamOffloadScanReq *) msg->bodyptr);
4718 break;
4719
4720 case WMA_RATE_UPDATE_IND:
4721 wma_process_rate_update_indicate(wma_handle,
4722 (tSirRateUpdateInd *) msg->bodyptr);
4723 break;
4724
4725#ifdef FEATURE_WLAN_TDLS
4726 case WMA_UPDATE_FW_TDLS_STATE:
4727 wma_update_fw_tdls_state(wma_handle,
4728 (t_wma_tdls_params *) msg->bodyptr);
4729 break;
4730 case WMA_UPDATE_TDLS_PEER_STATE:
4731 wma_update_tdls_peer_state(wma_handle,
4732 (tTdlsPeerStateParams *) msg->bodyptr);
4733 break;
4734 case WMA_TDLS_SET_OFFCHAN_MODE:
4735 wma_set_tdls_offchan_mode(wma_handle,
4736 (tdls_chan_switch_params *)msg->bodyptr);
4737 break;
4738#endif /* FEATURE_WLAN_TDLS */
4739 case WMA_ADD_PERIODIC_TX_PTRN_IND:
4740 wma_process_add_periodic_tx_ptrn_ind(wma_handle,
4741 (tSirAddPeriodicTxPtrn *) msg->bodyptr);
4742 cdf_mem_free(msg->bodyptr);
4743 break;
4744 case WMA_DEL_PERIODIC_TX_PTRN_IND:
4745 wma_process_del_periodic_tx_ptrn_ind(wma_handle,
4746 (tSirDelPeriodicTxPtrn *) msg->bodyptr);
4747 cdf_mem_free(msg->bodyptr);
4748 break;
4749 case WMA_TX_POWER_LIMIT:
4750 wma_process_tx_power_limits(wma_handle,
4751 (tSirTxPowerLimit *) msg->bodyptr);
4752 cdf_mem_free(msg->bodyptr);
4753 break;
4754#ifdef FEATURE_WLAN_LPHB
4755 case WMA_LPHB_CONF_REQ:
4756 wma_process_lphb_conf_req(wma_handle,
4757 (tSirLPHBReq *) msg->bodyptr);
4758 break;
4759#endif /* FEATURE_WLAN_LPHB */
4760
4761#ifdef FEATURE_WLAN_CH_AVOID
4762 case WMA_CH_AVOID_UPDATE_REQ:
4763 wma_process_ch_avoid_update_req(wma_handle,
4764 (tSirChAvoidUpdateReq *) msg->bodyptr);
4765 cdf_mem_free(msg->bodyptr);
4766 break;
4767#endif /* FEATURE_WLAN_CH_AVOID */
4768#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
4769 case WMA_SET_AUTO_SHUTDOWN_TIMER_REQ:
4770 wma_set_auto_shutdown_timer_req(wma_handle, msg->bodyptr);
4771 cdf_mem_free(msg->bodyptr);
4772 break;
4773#endif /* FEATURE_WLAN_AUTO_SHUTDOWN */
4774 case WMA_DHCP_START_IND:
4775 case WMA_DHCP_STOP_IND:
4776 wma_process_dhcp_ind(wma_handle, (tAniDHCPInd *) msg->bodyptr);
4777 cdf_mem_free(msg->bodyptr);
4778 break;
4779
4780 case WMA_INIT_THERMAL_INFO_CMD:
4781 wma_process_init_thermal_info(wma_handle,
4782 (t_thermal_mgmt *) msg->bodyptr);
4783 cdf_mem_free(msg->bodyptr);
4784 break;
4785
4786 case WMA_SET_THERMAL_LEVEL:
4787 wma_process_set_thermal_level(wma_handle, msg->bodyval);
4788 break;
4789
4790 case WMA_SET_P2P_GO_NOA_REQ:
4791 wma_process_set_p2pgo_noa_req(wma_handle,
4792 (tP2pPsParams *) msg->bodyptr);
4793 cdf_mem_free(msg->bodyptr);
4794 break;
4795 case WMA_SET_MIMOPS_REQ:
4796 wma_process_set_mimops_req(wma_handle,
4797 (tSetMIMOPS *) msg->bodyptr);
4798 cdf_mem_free(msg->bodyptr);
4799 break;
4800 case WMA_SET_SAP_INTRABSS_DIS:
4801 wma_set_vdev_intrabss_fwd(wma_handle,
4802 (tDisableIntraBssFwd *) msg->bodyptr);
4803 cdf_mem_free(msg->bodyptr);
4804 break;
4805 case WMA_GET_LINK_SPEED:
4806 wma_get_link_speed(wma_handle, msg->bodyptr);
4807 cdf_mem_free(msg->bodyptr);
4808 break;
4809 case WMA_MODEM_POWER_STATE_IND:
4810 wma_notify_modem_power_state(wma_handle,
4811 (tSirModemPowerStateInd *) msg->bodyptr);
4812 cdf_mem_free(msg->bodyptr);
4813 break;
4814 case WMA_WLAN_RESUME_REQ:
4815 wma_resume_req(wma_handle);
4816 break;
4817
4818#ifdef WLAN_FEATURE_STATS_EXT
4819 case WMA_STATS_EXT_REQUEST:
4820 wma_stats_ext_req(wma_handle,
4821 (tpStatsExtRequest) (msg->bodyptr));
4822 cdf_mem_free(msg->bodyptr);
4823 break;
4824#endif /* WLAN_FEATURE_STATS_EXT */
4825 case WMA_HIDDEN_SSID_VDEV_RESTART:
4826 wma_hidden_ssid_vdev_restart(wma_handle,
4827 (tHalHiddenSsidVdevRestart *) msg->bodyptr);
4828 cdf_mem_free(msg->bodyptr);
4829 break;
4830#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
4831 case WMA_WLAN_EXT_WOW:
4832 wma_enable_ext_wow(wma_handle,
4833 (tSirExtWoWParams *) msg->bodyptr);
4834 cdf_mem_free(msg->bodyptr);
4835 break;
4836 case WMA_WLAN_SET_APP_TYPE1_PARAMS:
4837 wma_set_app_type1_params_in_fw(wma_handle,
4838 (tSirAppType1Params *) msg->bodyptr);
4839 cdf_mem_free(msg->bodyptr);
4840 break;
4841 case WMA_WLAN_SET_APP_TYPE2_PARAMS:
4842 wma_set_app_type2_params_in_fw(wma_handle,
4843 (tSirAppType2Params *) msg->bodyptr);
4844 cdf_mem_free(msg->bodyptr);
4845 break;
4846#endif /* WLAN_FEATURE_EXTWOW_SUPPORT */
4847#ifdef FEATURE_WLAN_EXTSCAN
4848 case WMA_EXTSCAN_START_REQ:
4849 wma_start_extscan(wma_handle,
4850 (tSirWifiScanCmdReqParams *) msg->bodyptr);
4851 cdf_mem_free(msg->bodyptr);
4852 break;
4853 case WMA_EXTSCAN_STOP_REQ:
4854 wma_stop_extscan(wma_handle,
4855 (tSirExtScanStopReqParams *) msg->bodyptr);
4856 cdf_mem_free(msg->bodyptr);
4857 break;
4858 case WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ:
4859 wma_extscan_start_hotlist_monitor(wma_handle,
4860 (tSirExtScanSetBssidHotListReqParams *) msg->bodyptr);
4861 cdf_mem_free(msg->bodyptr);
4862 break;
4863 case WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ:
4864 wma_extscan_stop_hotlist_monitor(wma_handle,
4865 (tSirExtScanResetBssidHotlistReqParams *) msg->bodyptr);
4866 cdf_mem_free(msg->bodyptr);
4867 break;
4868 case WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ:
4869 wma_extscan_start_change_monitor(wma_handle,
4870 (tSirExtScanSetSigChangeReqParams *) msg->bodyptr);
4871 cdf_mem_free(msg->bodyptr);
4872 break;
4873 case WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ:
4874 wma_extscan_stop_change_monitor(wma_handle,
4875 (tSirExtScanResetSignificantChangeReqParams *) msg->bodyptr);
4876 cdf_mem_free(msg->bodyptr);
4877 break;
4878 case WMA_EXTSCAN_GET_CACHED_RESULTS_REQ:
4879 wma_extscan_get_cached_results(wma_handle,
4880 (tSirExtScanGetCachedResultsReqParams *) msg->bodyptr);
4881 cdf_mem_free(msg->bodyptr);
4882 break;
4883 case WMA_EXTSCAN_GET_CAPABILITIES_REQ:
4884 wma_extscan_get_capabilities(wma_handle,
4885 (tSirGetExtScanCapabilitiesReqParams *) msg->bodyptr);
4886 cdf_mem_free(msg->bodyptr);
4887 break;
4888 case WMA_SET_EPNO_LIST_REQ:
4889 wma_set_epno_network_list(wma_handle,
4890 (struct wifi_epno_params *)msg->bodyptr);
4891 cdf_mem_free(msg->bodyptr);
4892 break;
4893 case WMA_SET_PASSPOINT_LIST_REQ:
4894 /* Issue reset passpoint network list first and clear
4895 * the entries */
4896 wma_reset_passpoint_network_list(wma_handle,
4897 (struct wifi_passpoint_req *)msg->bodyptr);
4898
4899 wma_set_passpoint_network_list(wma_handle,
4900 (struct wifi_passpoint_req *)msg->bodyptr);
4901 cdf_mem_free(msg->bodyptr);
4902 break;
4903 case WMA_RESET_PASSPOINT_LIST_REQ:
4904 wma_reset_passpoint_network_list(wma_handle,
4905 (struct wifi_passpoint_req *)msg->bodyptr);
4906 break;
4907 case WMA_EXTSCAN_SET_SSID_HOTLIST_REQ:
4908 wma_set_ssid_hotlist(wma_handle,
4909 (struct sir_set_ssid_hotlist_request *)msg->bodyptr);
4910 cdf_mem_free(msg->bodyptr);
4911 break;
4912#endif /* FEATURE_WLAN_EXTSCAN */
4913 case WMA_SET_SCAN_MAC_OUI_REQ:
4914 wma_scan_probe_setoui(wma_handle, msg->bodyptr);
4915 cdf_mem_free(msg->bodyptr);
4916 break;
4917#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4918 case WMA_LINK_LAYER_STATS_CLEAR_REQ:
4919 wma_process_ll_stats_clear_req(wma_handle,
4920 (tpSirLLStatsClearReq) msg->bodyptr);
4921 cdf_mem_free(msg->bodyptr);
4922 break;
4923 case WMA_LINK_LAYER_STATS_SET_REQ:
4924 wma_process_ll_stats_set_req(wma_handle,
4925 (tpSirLLStatsSetReq) msg->bodyptr);
4926 cdf_mem_free(msg->bodyptr);
4927 break;
4928 case WMA_LINK_LAYER_STATS_GET_REQ:
4929 wma_process_ll_stats_get_req(wma_handle,
4930 (tpSirLLStatsGetReq) msg->bodyptr);
4931 cdf_mem_free(msg->bodyptr);
4932 break;
4933#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
4934 case SIR_HAL_UNIT_TEST_CMD:
4935 wma_process_unit_test_cmd(wma_handle,
4936 (t_wma_unit_test_cmd *) msg->bodyptr);
4937 cdf_mem_free(msg->bodyptr);
4938 break;
4939#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4940 case WMA_ROAM_OFFLOAD_SYNCH_CNF:
4941 wma_process_roam_synch_complete(wma_handle,
4942 (tSirSmeRoamOffloadSynchCnf *)msg->bodyptr);
4943 cdf_mem_free(msg->bodyptr);
4944 break;
4945 case WMA_ROAM_OFFLOAD_SYNCH_FAIL:
4946 wma_process_roam_synch_fail(wma_handle,
4947 (struct roam_offload_synch_fail *)msg->bodyptr);
4948 cdf_mem_free(msg->bodyptr);
4949 break;
4950 case SIR_HAL_ROAM_INVOKE:
4951 wma_process_roam_invoke(wma_handle,
4952 (struct wma_roam_invoke_cmd *)msg->bodyptr);
4953 cdf_mem_free(msg->bodyptr);
4954 break;
4955#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
4956#ifdef WLAN_FEATURE_NAN
4957 case WMA_NAN_REQUEST:
4958 wma_nan_req(wma_handle, (tNanRequest *) msg->bodyptr);
4959 cdf_mem_free(msg->bodyptr);
4960 break;
4961#endif /* WLAN_FEATURE_NAN */
4962 case SIR_HAL_SET_BASE_MACADDR_IND:
4963 wma_set_base_macaddr_indicate(wma_handle,
4964 (tSirMacAddr *) msg->bodyptr);
4965 cdf_mem_free(msg->bodyptr);
4966 break;
4967 case WMA_LINK_STATUS_GET_REQ:
4968 wma_process_link_status_req(wma_handle,
4969 (tAniGetLinkStatus *) msg->bodyptr);
4970 break;
4971 case WMA_GET_TEMPERATURE_REQ:
4972 wma_get_temperature(wma_handle);
4973 cdf_mem_free(msg->bodyptr);
4974 break;
4975#ifdef DHCP_SERVER_OFFLOAD
4976 case WMA_SET_DHCP_SERVER_OFFLOAD_CMD:
4977 wma_process_dhcpserver_offload(wma_handle,
4978 (tSirDhcpSrvOffloadInfo *) msg->bodyptr);
4979 cdf_mem_free(msg->bodyptr);
4980 break;
4981#endif /* DHCP_SERVER_OFFLOAD */
4982#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
4983 case WMA_LED_FLASHING_REQ:
4984 wma_set_led_flashing(wma_handle,
4985 (tSirLedFlashingReq *) msg->bodyptr);
4986 cdf_mem_free(msg->bodyptr);
4987 break;
4988#endif /* WLAN_FEATURE_GPIO_LED_FLASHING */
4989 case SIR_HAL_SET_MAS:
4990 wma_process_set_mas(wma_handle,
4991 (uint32_t *)msg->bodyptr);
4992 cdf_mem_free(msg->bodyptr);
4993 break;
4994 case SIR_HAL_SET_MIRACAST:
4995 wma_process_set_miracast(wma_handle,
4996 (uint32_t *)msg->bodyptr);
4997 cdf_mem_free(msg->bodyptr);
4998 break;
4999 case SIR_HAL_CONFIG_STATS_FACTOR:
5000 wma_config_stats_factor(wma_handle,
5001 (struct sir_stats_avg_factor *)
5002 msg->bodyptr);
5003 cdf_mem_free(msg->bodyptr);
5004 break;
5005 case SIR_HAL_CONFIG_GUARD_TIME:
5006 wma_config_guard_time(wma_handle,
5007 (struct sir_guard_time_request *)
5008 msg->bodyptr);
5009 case WMA_IPA_OFFLOAD_ENABLE_DISABLE:
5010 wma_ipa_offload_enable_disable(wma_handle,
5011 (struct sir_ipa_offload_enable_disable *)msg->bodyptr);
5012 cdf_mem_free(msg->bodyptr);
5013 break;
5014 case SIR_HAL_START_STOP_LOGGING:
5015 wma_set_wifi_start_packet_stats(wma_handle,
5016 (struct sir_wifi_start_log *)msg->bodyptr);
5017 wma_enable_specific_fw_logs(wma_handle,
5018 (struct sir_wifi_start_log *)msg->bodyptr);
5019 cdf_mem_free(msg->bodyptr);
5020 break;
5021 case SIR_HAL_FLUSH_LOG_TO_FW:
5022 wma_send_flush_logs_to_fw(wma_handle);
5023 /* Body ptr is NULL here */
5024 break;
5025 case WMA_SET_RSSI_MONITOR_REQ:
5026 wma_set_rssi_monitoring(wma_handle,
5027 (struct rssi_monitor_req *)msg->bodyptr);
5028 break;
5029 case WMA_FW_MEM_DUMP_REQ:
5030 wma_process_fw_mem_dump_req(wma_handle,
5031 (struct fw_dump_req *)msg->bodyptr);
5032 cdf_mem_free(msg->bodyptr);
5033 break;
5034 case SIR_HAL_SOC_SET_PCL_TO_FW:
5035 wma_send_soc_set_pcl_cmd(wma_handle,
5036 (struct sir_pcl_list *)msg->bodyptr);
5037 cdf_mem_free(msg->bodyptr);
5038 break;
5039 case SIR_HAL_SOC_SET_HW_MODE:
5040 wma_send_soc_set_hw_mode_cmd(wma_handle,
5041 (struct sir_hw_mode *)msg->bodyptr);
5042 cdf_mem_free(msg->bodyptr);
5043 break;
5044 case WMA_OCB_SET_CONFIG_CMD:
5045 wma_ocb_set_config_req(wma_handle,
5046 (struct sir_ocb_config *)msg->bodyptr);
5047 cdf_mem_free(msg->bodyptr);
5048 break;
5049 case WMA_OCB_SET_UTC_TIME_CMD:
5050 wma_ocb_set_utc_time(wma_handle,
5051 (struct sir_ocb_utc *)msg->bodyptr);
5052 cdf_mem_free(msg->bodyptr);
5053 break;
5054 case WMA_OCB_START_TIMING_ADVERT_CMD:
5055 wma_ocb_start_timing_advert(wma_handle,
5056 (struct sir_ocb_timing_advert *)msg->bodyptr);
5057 cdf_mem_free(msg->bodyptr);
5058 break;
5059 case WMA_OCB_STOP_TIMING_ADVERT_CMD:
5060 wma_ocb_stop_timing_advert(wma_handle,
5061 (struct sir_ocb_timing_advert *)msg->bodyptr);
5062 cdf_mem_free(msg->bodyptr);
5063 break;
5064 case WMA_DCC_CLEAR_STATS_CMD:
5065 wma_dcc_clear_stats(wma_handle,
5066 (struct sir_dcc_clear_stats *)msg->bodyptr);
5067 cdf_mem_free(msg->bodyptr);
5068 break;
5069 case WMA_OCB_GET_TSF_TIMER_CMD:
5070 wma_ocb_get_tsf_timer(wma_handle,
5071 (struct sir_ocb_get_tsf_timer *)msg->bodyptr);
5072 cdf_mem_free(msg->bodyptr);
5073 break;
5074 case WMA_DCC_GET_STATS_CMD:
5075 wma_dcc_get_stats(wma_handle,
5076 (struct sir_dcc_get_stats *)msg->bodyptr);
5077 cdf_mem_free(msg->bodyptr);
5078 break;
5079 case WMA_DCC_UPDATE_NDL_CMD:
5080 wma_dcc_update_ndl(wma_handle,
5081 (struct sir_dcc_update_ndl *)msg->bodyptr);
5082 cdf_mem_free(msg->bodyptr);
5083 break;
5084 case SIR_HAL_SOC_DUAL_MAC_CFG_REQ:
5085 wma_send_soc_set_dual_mac_config(wma_handle,
5086 (struct sir_dual_mac_config *)msg->bodyptr);
5087 cdf_mem_free(msg->bodyptr);
5088 break;
5089 case WMA_SET_IE_INFO:
5090 wma_process_set_ie_info(wma_handle,
5091 (struct vdev_ie_info *)msg->bodyptr);
5092 cdf_mem_free(msg->bodyptr);
5093 break;
5094 case WMA_LRO_CONFIG_CMD:
5095 wma_lro_config_cmd(wma_handle,
5096 (struct wma_lro_config_cmd_t *)msg->bodyptr);
5097 cdf_mem_free(msg->bodyptr);
5098 break;
5099 default:
5100 WMA_LOGD("unknow msg type %x", msg->type);
5101 /* Do Nothing? MSG Body should be freed at here */
5102 if (NULL != msg->bodyptr) {
5103 cdf_mem_free(msg->bodyptr);
5104 }
5105 }
5106end:
5107 WMA_LOGI("%s: Exit", __func__);
5108 return cdf_status;
5109}
5110
5111/**
5112 * wma_log_completion_timeout() - Log completion timeout
5113 * @data: Timeout handler data
5114 *
5115 * This function is called when log completion timer expires
5116 *
5117 * Return: None
5118 */
5119void wma_log_completion_timeout(void *data)
5120{
5121 tp_wma_handle wma_handle;
5122
5123 WMA_LOGE("%s: Timeout occured for log completion command", __func__);
5124
5125 wma_handle = (tp_wma_handle) data;
5126 if (!wma_handle)
5127 WMA_LOGE("%s: Invalid WMA handle", __func__);
5128
5129 /* Though we did not receive any event from FW,
5130 * we can flush whatever logs we have with us */
5131 cds_logging_set_fw_flush_complete();
5132
5133 return;
5134}
5135
5136/**
5137 * wma_send_soc_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW
5138 * @wma_handle: WMA handle
5139 * @msg: PCL structure containing the PCL and the number of channels
5140 *
5141 * WMI_SOC_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
5142 * firmware. The DBS Manager is the consumer of this information in the WLAN
5143 * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
5144 * to migrate to a new channel without host driver involvement. An example of
5145 * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
5146 * manage the channel selection without firmware involvement.
5147 *
5148 * Return: Success if the cmd is sent successfully to the firmware
5149 */
5150CDF_STATUS wma_send_soc_set_pcl_cmd(tp_wma_handle wma_handle,
5151 struct sir_pcl_list *msg)
5152{
5153 wmi_soc_set_pcl_cmd_fixed_param *cmd;
5154 wmi_buf_t buf;
5155 uint8_t *buf_ptr;
5156 uint32_t *cmd_args, i, len;
5157
5158 if (!wma_handle) {
5159 WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
5160 __func__);
5161 return CDF_STATUS_E_NULL_VALUE;
5162 }
5163
5164 len = sizeof(*cmd) +
5165 WMI_TLV_HDR_SIZE + (msg->pcl_len * sizeof(uint32_t));
5166
5167 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
5168 if (!buf) {
5169 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
5170 return CDF_STATUS_E_NOMEM;
5171 }
5172
5173 cmd = (wmi_soc_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
5174 buf_ptr = (uint8_t *) cmd;
5175 WMITLV_SET_HDR(&cmd->tlv_header,
5176 WMITLV_TAG_STRUC_wmi_soc_set_pcl_cmd_fixed_param,
5177 WMITLV_GET_STRUCT_TLVLEN(wmi_soc_set_pcl_cmd_fixed_param));
5178 cmd->num_chan = msg->pcl_len;
5179 WMA_LOGI("%s: PCL len:%d", __func__, cmd->num_chan);
5180
5181 buf_ptr += sizeof(wmi_soc_set_pcl_cmd_fixed_param);
5182 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
5183 (msg->pcl_len * sizeof(uint32_t)));
5184 cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
5185 for (i = 0; i < msg->pcl_len ; i++) {
5186 cmd_args[i] = msg->pcl_list[i];
5187 WMA_LOGI("%s: PCL chan:%d", __func__, cmd_args[i]);
5188 }
5189 if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
5190 WMI_SOC_SET_PCL_CMDID)) {
5191 WMA_LOGE("%s: Failed to send WMI_SOC_SET_PCL_CMDID", __func__);
5192 cdf_nbuf_free(buf);
5193 return CDF_STATUS_E_FAILURE;
5194 }
5195 return CDF_STATUS_SUCCESS;
5196}
5197
5198/**
5199 * wma_send_soc_set_hw_mode_cmd() - Send WMI_SOC_SET_HW_MODE_CMDID to FW
5200 * @wma_handle: WMA handle
5201 * @msg: Structure containing the following parameters
5202 *
5203 * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
5204 * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
5205 *
5206 * Provides notification to the WLAN firmware that host driver is requesting a
5207 * HardWare (HW) Mode change. This command is needed to support iHelium in the
5208 * configurations that include the Dual Band Simultaneous (DBS) feature.
5209 *
5210 * Return: Success if the cmd is sent successfully to the firmware
5211 */
5212CDF_STATUS wma_send_soc_set_hw_mode_cmd(tp_wma_handle wma_handle,
5213 struct sir_hw_mode *msg)
5214{
5215 wmi_soc_set_hw_mode_cmd_fixed_param *cmd;
5216 wmi_buf_t buf;
5217 uint32_t len;
5218 struct sir_set_hw_mode_resp *param;
5219
5220 if (!wma_handle) {
5221 WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
5222 __func__);
5223 /* Handle is NULL. Will not be able to send failure
5224 * response as well
5225 */
5226 return CDF_STATUS_E_NULL_VALUE;
5227 }
5228
5229 if (!msg) {
5230 WMA_LOGE("%s: Set HW mode param is NULL", __func__);
5231 /* Lets try to free the active command list */
5232 goto fail;
5233 }
5234
5235 len = sizeof(*cmd);
5236
5237 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
5238 if (!buf) {
5239 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
5240 goto fail;
5241 }
5242
5243 cmd = (wmi_soc_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
5244 WMITLV_SET_HDR(&cmd->tlv_header,
5245 WMITLV_TAG_STRUC_wmi_soc_set_hw_mode_cmd_fixed_param,
5246 WMITLV_GET_STRUCT_TLVLEN(wmi_soc_set_hw_mode_cmd_fixed_param));
5247 cmd->hw_mode_index = msg->hw_mode_index;
5248 WMA_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
5249
5250 if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
5251 WMI_SOC_SET_HW_MODE_CMDID)) {
5252 WMA_LOGE("%s: Failed to send WMI_SOC_SET_HW_MODE_CMDID",
5253 __func__);
5254 cdf_nbuf_free(buf);
5255 goto fail;
5256 }
5257 return CDF_STATUS_SUCCESS;
5258fail:
5259 param = cdf_mem_malloc(sizeof(*param));
5260 if (!param) {
5261 WMA_LOGE("%s: Memory allocation failed", __func__);
5262 return CDF_STATUS_E_NULL_VALUE;
5263 }
5264 param->status = SET_HW_MODE_STATUS_ECANCELED;
5265 param->cfgd_hw_mode_index = 0;
5266 param->num_vdev_mac_entries = 0;
5267 WMA_LOGE("%s: Sending HW mode fail response to LIM", __func__);
5268 wma_send_msg(wma_handle, SIR_HAL_SOC_SET_HW_MODE_RESP,
5269 (void *) param, 0);
5270 return CDF_STATUS_SUCCESS;
5271}
5272
5273/**
5274 * wma_send_soc_set_dual_mac_config() - Set dual mac config to FW
5275 * @wma_handle: WMA handle
5276 * @msg: Dual MAC config parameters
5277 *
5278 * Configures WLAN firmware with the dual MAC features
5279 *
5280 * Return: CDF_STATUS. 0 on success.
5281 */
5282CDF_STATUS wma_send_soc_set_dual_mac_config(tp_wma_handle wma_handle,
5283 struct sir_dual_mac_config *msg)
5284{
5285 wmi_soc_set_dual_mac_config_cmd_fixed_param *cmd;
5286 wmi_buf_t buf;
5287 uint32_t len;
5288
5289 if (!wma_handle) {
5290 WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
5291 __func__);
5292 return CDF_STATUS_E_NULL_VALUE;
5293 }
5294
5295 if (!msg) {
5296 WMA_LOGE("%s: Set dual mode config is NULL", __func__);
5297 return CDF_STATUS_E_NULL_VALUE;
5298 }
5299
5300 len = sizeof(*cmd);
5301
5302 buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
5303 if (!buf) {
5304 WMA_LOGE("%s: wmi_buf_alloc failed", __func__);
5305 return CDF_STATUS_E_FAILURE;
5306 }
5307
5308 cmd = (wmi_soc_set_dual_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
5309 WMITLV_SET_HDR(&cmd->tlv_header,
5310 WMITLV_TAG_STRUC_wmi_soc_set_dual_mac_config_cmd_fixed_param,
5311 WMITLV_GET_STRUCT_TLVLEN(
5312 wmi_soc_set_dual_mac_config_cmd_fixed_param));
5313 cmd->concurrent_scan_config_bits = msg->scan_config;
5314 cmd->fw_mode_config_bits = msg->fw_mode_config;
5315 WMA_LOGI("%s: scan_config:%x fw_mode_config:%x",
5316 __func__, msg->scan_config, msg->fw_mode_config);
5317
5318 wma_handle->dual_mac_cfg.req_scan_config = msg->scan_config;
5319 wma_handle->dual_mac_cfg.req_fw_mode_config = msg->fw_mode_config;
5320
5321 if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
5322 WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID)) {
5323 WMA_LOGE("%s: Failed to send WMI_SOC_SET_DUAL_MAC_CONFIG_CMDID",
5324 __func__);
5325 cdf_nbuf_free(buf);
5326 }
5327 return CDF_STATUS_SUCCESS;
5328}
5329
5330/**
5331 * wma_crash_inject() - sends command to FW to simulate crash
5332 * @wma_handle: pointer of WMA context
5333 * @type: subtype of the command
5334 * @delay_time_ms: time in milliseconds for FW to delay the crash
5335 *
5336 * This function will send a command to FW in order to simulate different
5337 * kinds of FW crashes.
5338 *
5339 * Return: 0 for success or reasons for failure
5340 */
5341int wma_crash_inject(tp_wma_handle wma_handle, uint32_t type,
5342 uint32_t delay_time_ms)
5343{
5344 return wmi_crash_inject(wma_handle->wmi_handle, type, delay_time_ms);
5345}
5346#if defined(FEATURE_LRO)
5347/**
5348 * wma_lro_init() - sends LRO configuration to FW
5349 * @lro_config: pointer to the config parameters
5350 *
5351 * This function ends LRO configuration to FW.
5352 *
5353 * Return: 0 for success or reasons for failure
5354 */
5355int wma_lro_init(struct wma_lro_config_cmd_t *lro_config)
5356{
5357 cds_msg_t msg = {0};
5358 struct wma_lro_config_cmd_t *iwcmd;
5359
5360 iwcmd = cdf_mem_malloc(sizeof(*iwcmd));
5361 if (!iwcmd) {
5362 WMA_LOGE("memory allocation for WMA_LRO_CONFIG_CMD failed!");
5363 return -ENOMEM;
5364 }
5365
5366 *iwcmd = *lro_config;
5367
5368 msg.type = WMA_LRO_CONFIG_CMD;
5369 msg.reserved = 0;
5370 msg.bodyptr = iwcmd;
5371
5372 if (CDF_STATUS_SUCCESS !=
5373 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
5374 WMA_LOGE("Failed to post WMA_LRO_CONFIG_CMD msg!");
5375 cdf_mem_free(iwcmd);
5376 return -EAGAIN;
5377 }
5378
5379 WMA_LOGD("sending the LRO configuration to the fw");
5380 return 0;
5381}
5382#endif