xref: /wlan-dirver/platform/icnss2/qmi.c (revision e409b8c5d28a1d755d06779aa2a338e04ac72984)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #define pr_fmt(fmt) "icnss2_qmi: " fmt
8 
9 #include <linux/export.h>
10 #include <linux/err.h>
11 #include <linux/of.h>
12 #include <linux/init.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/etherdevice.h>
17 #include <linux/seq_file.h>
18 #include <linux/slab.h>
19 #include <linux/delay.h>
20 #include <linux/ipc_logging.h>
21 #include <linux/thread_info.h>
22 #include <linux/firmware.h>
23 #include <linux/soc/qcom/qmi.h>
24 #include <linux/platform_device.h>
25 #ifdef CONFIG_CNSS_OUT_OF_TREE
26 #include "icnss2.h"
27 #else
28 #include <soc/qcom/icnss2.h>
29 #endif
30 #include <soc/qcom/of_common.h>
31 #include "wlan_firmware_service_v01.h"
32 #include "main.h"
33 #include "qmi.h"
34 #include "debug.h"
35 #include "genl.h"
36 
37 #define WLFW_SERVICE_WCN_INS_ID_V01	3
38 #define WLFW_SERVICE_INS_ID_V01		0
39 #define WLFW_CLIENT_ID			0x4b4e454c
40 #define QMI_ERR_PLAT_CCPM_CLK_INIT_FAILED	0x77
41 
42 #define BDF_FILE_NAME_PREFIX		"bdwlan"
43 #define ELF_BDF_FILE_NAME		"bdwlan.elf"
44 #define ELF_BDF_FILE_NAME_PREFIX	"bdwlan.e"
45 #define BIN_BDF_FILE_NAME		"bdwlan.bin"
46 #define BIN_BDF_FILE_NAME_PREFIX	"bdwlan."
47 #define REGDB_FILE_NAME			"regdb.bin"
48 
49 #define QDSS_TRACE_CONFIG_FILE "qdss_trace_config.cfg"
50 
51 #define WLAN_BOARD_ID_INDEX		0x100
52 #define DEVICE_BAR_SIZE			0x200000
53 #define M3_SEGMENT_ADDR_MASK		0xFFFFFFFF
54 #define DMS_QMI_MAX_MSG_LEN		SZ_256
55 #define DMS_MAC_NOT_PROVISIONED		16
56 #define BDWLAN_SIZE			6
57 #define UMC_CHIP_ID                    0x4320
58 #define MAX_SHADOW_REG_RESERVED		2
59 #define MAX_NUM_SHADOW_REG_V3		(QMI_WLFW_MAX_NUM_SHADOW_REG_V3_USAGE_V01 - \
60 					MAX_SHADOW_REG_RESERVED)
61 #define IMSPRIVATE_SERVICE_MAX_MSG_LEN  SZ_8K
62 
63 #ifdef CONFIG_ICNSS2_DEBUG
64 bool ignore_fw_timeout;
65 #define ICNSS_QMI_ASSERT() ICNSS_ASSERT(ignore_fw_timeout)
66 #else
67 #define ICNSS_QMI_ASSERT() do { } while (0)
68 #endif
69 
70 #ifdef CONFIG_ICNSS2_DEBUG
71 void icnss_ignore_fw_timeout(bool ignore)
72 {
73 	ignore_fw_timeout = ignore;
74 }
75 #else
76 void icnss_ignore_fw_timeout(bool ignore) { }
77 #endif
78 
79 #define icnss_qmi_fatal_err(_fmt, ...) do {		\
80 	icnss_pr_err("fatal: "_fmt, ##__VA_ARGS__);	\
81 	ICNSS_QMI_ASSERT();				\
82 	} while (0)
83 
84 int wlfw_msa_mem_info_send_sync_msg(struct icnss_priv *priv)
85 {
86 	int ret;
87 	int i;
88 	struct wlfw_msa_info_req_msg_v01 *req;
89 	struct wlfw_msa_info_resp_msg_v01 *resp;
90 	struct qmi_txn txn;
91 	uint64_t max_mapped_addr;
92 
93 	if (!priv)
94 		return -ENODEV;
95 
96 	icnss_pr_dbg("Sending MSA mem info, state: 0x%lx\n", priv->state);
97 
98 	req = kzalloc(sizeof(*req), GFP_KERNEL);
99 	if (!req)
100 		return -ENOMEM;
101 
102 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
103 	if (!resp) {
104 		kfree(req);
105 		return -ENOMEM;
106 	}
107 
108 	req->msa_addr = priv->msa_pa;
109 	req->size = priv->msa_mem_size;
110 
111 	priv->stats.msa_info_req++;
112 
113 	ret = qmi_txn_init(&priv->qmi, &txn,
114 			   wlfw_msa_info_resp_msg_v01_ei, resp);
115 	if (ret < 0) {
116 		icnss_qmi_fatal_err(
117 				"Fail to init txn for MSA Mem info resp %d\n",
118 			     ret);
119 		goto out;
120 	}
121 
122 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
123 			       QMI_WLFW_MSA_INFO_REQ_V01,
124 			       WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN,
125 			       wlfw_msa_info_req_msg_v01_ei, req);
126 	if (ret < 0) {
127 		qmi_txn_cancel(&txn);
128 		icnss_qmi_fatal_err("Fail to send MSA Mem info req %d\n", ret);
129 		goto out;
130 	}
131 
132 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
133 	if (ret < 0) {
134 		icnss_qmi_fatal_err("MSA Mem info resp wait failed ret %d\n",
135 				    ret);
136 		goto out;
137 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
138 		icnss_qmi_fatal_err(
139 		"QMI MSA Mem info request rejected, result:%d error:%d\n",
140 			resp->resp.result, resp->resp.error);
141 		ret = -resp->resp.result;
142 		goto out;
143 	}
144 
145 	icnss_pr_dbg("Receive mem_region_info_len: %d\n",
146 		     resp->mem_region_info_len);
147 
148 	if (resp->mem_region_info_len > QMI_WLFW_MAX_NUM_MEMORY_REGIONS_V01) {
149 		icnss_qmi_fatal_err(
150 			"Invalid memory region length received: %d\n",
151 			 resp->mem_region_info_len);
152 		ret = -EINVAL;
153 		goto out;
154 	}
155 
156 	max_mapped_addr = priv->msa_pa + priv->msa_mem_size;
157 	priv->stats.msa_info_resp++;
158 	priv->nr_mem_region = resp->mem_region_info_len;
159 	for (i = 0; i < resp->mem_region_info_len; i++) {
160 
161 		if (resp->mem_region_info[i].size > priv->msa_mem_size ||
162 		    resp->mem_region_info[i].region_addr >= max_mapped_addr ||
163 		    resp->mem_region_info[i].region_addr < priv->msa_pa ||
164 		    resp->mem_region_info[i].size +
165 		    resp->mem_region_info[i].region_addr > max_mapped_addr) {
166 			icnss_pr_dbg("Received out of range Addr: 0x%llx Size: 0x%x\n",
167 					resp->mem_region_info[i].region_addr,
168 					resp->mem_region_info[i].size);
169 			ret = -EINVAL;
170 			goto fail_unwind;
171 		}
172 
173 		priv->mem_region[i].reg_addr =
174 			resp->mem_region_info[i].region_addr;
175 		priv->mem_region[i].size =
176 			resp->mem_region_info[i].size;
177 		priv->mem_region[i].secure_flag =
178 			resp->mem_region_info[i].secure_flag;
179 		icnss_pr_dbg("Memory Region: %d Addr: 0x%llx Size: 0x%x Flag: 0x%08x\n",
180 			     i, priv->mem_region[i].reg_addr,
181 			     priv->mem_region[i].size,
182 			     priv->mem_region[i].secure_flag);
183 	}
184 
185 	kfree(resp);
186 	kfree(req);
187 	return 0;
188 
189 fail_unwind:
190 	memset(&priv->mem_region[0], 0, sizeof(priv->mem_region[0]) * i);
191 out:
192 	kfree(resp);
193 	kfree(req);
194 	priv->stats.msa_info_err++;
195 	return ret;
196 }
197 
198 int wlfw_msa_ready_send_sync_msg(struct icnss_priv *priv)
199 {
200 	int ret;
201 	struct wlfw_msa_ready_req_msg_v01 *req;
202 	struct wlfw_msa_ready_resp_msg_v01 *resp;
203 	struct qmi_txn txn;
204 
205 	if (!priv)
206 		return -ENODEV;
207 
208 	icnss_pr_dbg("Sending MSA ready request message, state: 0x%lx\n",
209 		     priv->state);
210 
211 	req = kzalloc(sizeof(*req), GFP_KERNEL);
212 	if (!req)
213 		return -ENOMEM;
214 
215 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
216 	if (!resp) {
217 		kfree(req);
218 		return -ENOMEM;
219 	}
220 
221 	priv->stats.msa_ready_req++;
222 
223 	ret = qmi_txn_init(&priv->qmi, &txn,
224 			   wlfw_msa_ready_resp_msg_v01_ei, resp);
225 	if (ret < 0) {
226 		icnss_qmi_fatal_err(
227 				"Fail to init txn for MSA Mem Ready resp %d\n",
228 				ret);
229 		goto out;
230 	}
231 
232 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
233 			       QMI_WLFW_MSA_READY_REQ_V01,
234 			       WLFW_MSA_READY_REQ_MSG_V01_MAX_MSG_LEN,
235 			       wlfw_msa_ready_req_msg_v01_ei, req);
236 	if (ret < 0) {
237 		qmi_txn_cancel(&txn);
238 		icnss_qmi_fatal_err("Fail to send MSA Mem Ready req %d\n", ret);
239 		goto out;
240 	}
241 
242 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
243 	if (ret < 0) {
244 		icnss_qmi_fatal_err(
245 				"MSA Mem Ready resp wait failed with ret %d\n",
246 				ret);
247 		goto out;
248 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
249 		icnss_qmi_fatal_err(
250 		   "QMI MSA Mem Ready request rejected, result:%d error:%d\n",
251 		   resp->resp.result, resp->resp.error);
252 		ret = -resp->resp.result;
253 		goto out;
254 	}
255 
256 	priv->stats.msa_ready_resp++;
257 
258 	kfree(resp);
259 	kfree(req);
260 	return 0;
261 
262 out:
263 	kfree(resp);
264 	kfree(req);
265 	priv->stats.msa_ready_err++;
266 	return ret;
267 }
268 
269 int wlfw_device_info_send_msg(struct icnss_priv *priv)
270 {
271 	int ret;
272 	struct wlfw_device_info_req_msg_v01 *req;
273 	struct wlfw_device_info_resp_msg_v01 *resp;
274 	struct qmi_txn txn;
275 
276 	if (!priv)
277 		return -ENODEV;
278 
279 	icnss_pr_dbg("Sending Device Info request message, state: 0x%lx\n",
280 		     priv->state);
281 
282 	req = kzalloc(sizeof(*req), GFP_KERNEL);
283 	if (!req)
284 		return -ENOMEM;
285 
286 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
287 	if (!resp) {
288 		kfree(req);
289 		return -ENOMEM;
290 	}
291 
292 	priv->stats.device_info_req++;
293 
294 	ret = qmi_txn_init(&priv->qmi, &txn,
295 			   wlfw_device_info_resp_msg_v01_ei, resp);
296 	if (ret < 0) {
297 		icnss_qmi_fatal_err(
298 				"Fail to init txn for Device Info resp %d\n",
299 				ret);
300 		goto out;
301 	}
302 
303 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
304 			       QMI_WLFW_DEVICE_INFO_REQ_V01,
305 			       WLFW_DEVICE_INFO_REQ_MSG_V01_MAX_MSG_LEN,
306 			       wlfw_device_info_req_msg_v01_ei, req);
307 	if (ret < 0) {
308 		qmi_txn_cancel(&txn);
309 		icnss_qmi_fatal_err("Fail to send device info req %d\n", ret);
310 		goto out;
311 	}
312 
313 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
314 	if (ret < 0) {
315 		icnss_qmi_fatal_err(
316 				"Device Info resp wait failed with ret %d\n",
317 				ret);
318 		goto out;
319 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
320 		icnss_qmi_fatal_err(
321 		   "QMI Device info request rejected, result:%d error:%d\n",
322 		   resp->resp.result, resp->resp.error);
323 		ret = -resp->resp.result;
324 		goto out;
325 	}
326 
327 	priv->stats.device_info_resp++;
328 
329 	if (resp->bar_addr_valid)
330 		priv->mem_base_pa = resp->bar_addr;
331 
332 	if (resp->bar_size_valid)
333 		priv->mem_base_size = resp->bar_size;
334 
335 	if (!priv->mem_base_pa) {
336 		ret = -EINVAL;
337 		icnss_qmi_fatal_err("Fail to get bar address\n");
338 		goto out;
339 	}
340 
341 	if (priv->mem_base_size <  DEVICE_BAR_SIZE) {
342 		ret = -EINVAL;
343 		icnss_qmi_fatal_err("Bar size is not proper 0x%x\n",
344 				    priv->mem_base_size);
345 		goto out;
346 	}
347 
348 	if (resp->mhi_state_info_addr_valid)
349 		priv->mhi_state_info_pa = resp->mhi_state_info_addr;
350 
351 	if (resp->mhi_state_info_size_valid)
352 		priv->mhi_state_info_size = resp->mhi_state_info_size;
353 
354 	if (!priv->mhi_state_info_pa)
355 		icnss_pr_err("Fail to get MHI info address\n");
356 
357 	kfree(resp);
358 	kfree(req);
359 	return 0;
360 
361 out:
362 	kfree(resp);
363 	kfree(req);
364 	priv->stats.device_info_err++;
365 	return ret;
366 }
367 
368 int wlfw_power_save_send_msg(struct icnss_priv *priv,
369 			     enum wlfw_power_save_mode_v01 mode)
370 {
371 	int ret;
372 	struct wlfw_power_save_req_msg_v01 *req;
373 	struct qmi_txn txn;
374 
375 	if (!priv)
376 		return -ENODEV;
377 
378 	if (test_bit(ICNSS_FW_DOWN, &priv->state))
379 		return -EINVAL;
380 
381 	if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
382 	    !test_bit(ICNSS_MODE_ON, &priv->state))
383 		return 0;
384 
385 	icnss_pr_dbg("Sending power save mode: %d, state: 0x%lx\n",
386 		     mode, priv->state);
387 
388 	req = kzalloc(sizeof(*req), GFP_KERNEL);
389 	if (!req)
390 		return -ENOMEM;
391 
392 	req->power_save_mode_valid = 1;
393 	req->power_save_mode = mode;
394 
395 	if (mode == WLFW_POWER_SAVE_EXIT_V01)
396 		priv->stats.exit_power_save_req++;
397 	else
398 		priv->stats.enter_power_save_req++;
399 
400 	ret = qmi_txn_init(&priv->qmi, &txn,
401 			   NULL, NULL);
402 	if (ret < 0) {
403 		icnss_qmi_fatal_err("Fail to init txn for exit power save%d\n",
404 				    ret);
405 		goto out;
406 	}
407 
408 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
409 			       QMI_WLFW_POWER_SAVE_REQ_V01,
410 			       WLFW_POWER_SAVE_REQ_MSG_V01_MAX_MSG_LEN,
411 			       wlfw_power_save_req_msg_v01_ei, req);
412 	if (ret < 0) {
413 		qmi_txn_cancel(&txn);
414 		icnss_qmi_fatal_err("Fail to send exit power save req %d\n",
415 				    ret);
416 		goto out;
417 	}
418 
419 	qmi_txn_cancel(&txn);
420 
421 	if (mode == WLFW_POWER_SAVE_EXIT_V01)
422 		priv->stats.exit_power_save_resp++;
423 	else
424 		priv->stats.enter_power_save_resp++;
425 
426 	kfree(req);
427 	return 0;
428 
429 out:
430 	kfree(req);
431 
432 	if (mode == WLFW_POWER_SAVE_EXIT_V01)
433 		priv->stats.exit_power_save_err++;
434 	else
435 		priv->stats.enter_power_save_err++;
436 	return ret;
437 }
438 
439 int wlfw_send_soc_wake_msg(struct icnss_priv *priv,
440 			   enum wlfw_soc_wake_enum_v01 type)
441 {
442 	int ret;
443 	struct wlfw_soc_wake_req_msg_v01 *req;
444 	struct wlfw_soc_wake_resp_msg_v01 *resp;
445 	struct qmi_txn txn;
446 
447 	if (!priv)
448 		return -ENODEV;
449 
450 	if (test_bit(ICNSS_FW_DOWN, &priv->state))
451 		return -EINVAL;
452 
453 	icnss_pr_soc_wake("Sending soc wake msg, type: 0x%x\n",
454 		     type);
455 
456 	req = kzalloc(sizeof(*req), GFP_KERNEL);
457 	if (!req)
458 		return -ENOMEM;
459 
460 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
461 	if (!resp) {
462 		kfree(req);
463 		return -ENOMEM;
464 	}
465 	req->wake_valid = 1;
466 	req->wake = type;
467 
468 	priv->stats.soc_wake_req++;
469 
470 	ret = qmi_txn_init(&priv->qmi, &txn,
471 			   wlfw_soc_wake_resp_msg_v01_ei, resp);
472 
473 	if (ret < 0) {
474 		icnss_pr_err("Fail to init txn for wake msg resp %d\n",
475 			     ret);
476 		goto out;
477 	}
478 
479 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
480 			       QMI_WLFW_SOC_WAKE_REQ_V01,
481 			       WLFW_SOC_WAKE_REQ_MSG_V01_MAX_MSG_LEN,
482 			       wlfw_soc_wake_req_msg_v01_ei, req);
483 	if (ret < 0) {
484 		qmi_txn_cancel(&txn);
485 		icnss_pr_err("Fail to send soc wake msg %d\n", ret);
486 		goto out;
487 	}
488 
489 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
490 	if (ret < 0) {
491 		icnss_qmi_fatal_err("SOC wake timed out with ret %d\n",
492 				    ret);
493 		goto out;
494 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
495 		icnss_qmi_fatal_err(
496 			"SOC wake request rejected,result:%d error:%d\n",
497 			resp->resp.result, resp->resp.error);
498 		ret = -resp->resp.result;
499 		goto out;
500 	}
501 
502 	priv->stats.soc_wake_resp++;
503 
504 	kfree(resp);
505 	kfree(req);
506 	return 0;
507 
508 out:
509 	kfree(req);
510 	kfree(resp);
511 	priv->stats.soc_wake_err++;
512 	return ret;
513 }
514 
515 int wlfw_ind_register_send_sync_msg(struct icnss_priv *priv)
516 {
517 	int ret;
518 	struct wlfw_ind_register_req_msg_v01 *req;
519 	struct wlfw_ind_register_resp_msg_v01 *resp;
520 	struct qmi_txn txn;
521 
522 	if (!priv)
523 		return -ENODEV;
524 
525 	icnss_pr_dbg("Sending indication register message, state: 0x%lx\n",
526 		     priv->state);
527 
528 	req = kzalloc(sizeof(*req), GFP_KERNEL);
529 	if (!req)
530 		return -ENOMEM;
531 
532 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
533 	if (!resp) {
534 		kfree(req);
535 		return -ENOMEM;
536 	}
537 
538 	req->client_id_valid = 1;
539 	req->client_id = WLFW_CLIENT_ID;
540 	req->fw_ready_enable_valid = 1;
541 	req->fw_ready_enable = 1;
542 	req->pin_connect_result_enable_valid = 1;
543 	req->pin_connect_result_enable = 1;
544 
545 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
546 		req->msa_ready_enable_valid = 1;
547 		req->msa_ready_enable = 1;
548 		if (test_bit(FW_REJUVENATE_ENABLE,
549 			 &priv->ctrl_params.quirks)) {
550 			req->rejuvenate_enable_valid = 1;
551 			req->rejuvenate_enable = 1;
552 		}
553 	} else if (priv->device_id == WCN6750_DEVICE_ID ||
554 		   priv->device_id == WCN6450_DEVICE_ID) {
555 		req->fw_init_done_enable_valid = 1;
556 		req->fw_init_done_enable = 1;
557 		req->cal_done_enable_valid = 1;
558 		req->cal_done_enable = 1;
559 		req->qdss_trace_req_mem_enable_valid = 1;
560 		req->qdss_trace_req_mem_enable = 1;
561 		req->qdss_trace_save_enable_valid = 1;
562 		req->qdss_trace_save_enable = 1;
563 		req->qdss_trace_free_enable_valid = 1;
564 		req->qdss_trace_free_enable = 1;
565 		req->respond_get_info_enable_valid = 1;
566 		req->respond_get_info_enable = 1;
567 		req->m3_dump_upload_segments_req_enable_valid = 1;
568 		req->m3_dump_upload_segments_req_enable = 1;
569 	}
570 
571 	priv->stats.ind_register_req++;
572 
573 	ret = qmi_txn_init(&priv->qmi, &txn,
574 			   wlfw_ind_register_resp_msg_v01_ei, resp);
575 	if (ret < 0) {
576 		icnss_qmi_fatal_err(
577 				"Fail to init txn for Ind Register resp %d\n",
578 			     ret);
579 		goto out;
580 	}
581 
582 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
583 			       QMI_WLFW_IND_REGISTER_REQ_V01,
584 			       WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN,
585 			       wlfw_ind_register_req_msg_v01_ei, req);
586 	if (ret < 0) {
587 		qmi_txn_cancel(&txn);
588 		icnss_qmi_fatal_err("Fail to send Ind Register req %d\n", ret);
589 		goto out;
590 	}
591 
592 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
593 	if (ret < 0) {
594 		icnss_qmi_fatal_err(
595 			"Ind Register resp wait failed with ret %d\n",
596 			 ret);
597 		goto out;
598 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
599 		icnss_qmi_fatal_err(
600 		    "QMI Ind Register request rejected, result:%d error:%d\n",
601 		     resp->resp.result, resp->resp.error);
602 		ret = -resp->resp.result;
603 		goto out;
604 	}
605 
606 	priv->stats.ind_register_resp++;
607 
608 	if (resp->fw_status_valid &&
609 	   (resp->fw_status & QMI_WLFW_ALREADY_REGISTERED_V01)) {
610 		ret = -EALREADY;
611 		icnss_pr_dbg("WLFW already registered\n");
612 		goto qmi_registered;
613 	}
614 
615 	kfree(resp);
616 	kfree(req);
617 
618 	return 0;
619 
620 out:
621 	priv->stats.ind_register_err++;
622 qmi_registered:
623 	kfree(resp);
624 	kfree(req);
625 	return ret;
626 }
627 
628 int wlfw_cal_report_req(struct icnss_priv *priv)
629 {
630 	int ret;
631 	struct wlfw_cal_report_req_msg_v01 *req;
632 	struct wlfw_cal_report_resp_msg_v01 *resp;
633 	struct qmi_txn txn;
634 
635 	if (!priv)
636 		return -ENODEV;
637 
638 	if (test_bit(ICNSS_FW_DOWN, &priv->state))
639 		return -EINVAL;
640 
641 	icnss_pr_info("Sending cal report request, state: 0x%lx\n",
642 		      priv->state);
643 
644 	req = kzalloc(sizeof(*req), GFP_KERNEL);
645 	if (!req)
646 		return -ENOMEM;
647 
648 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
649 	if (!resp) {
650 		kfree(req);
651 		return -ENOMEM;
652 	}
653 	req->meta_data_len = 0;
654 
655 	ret = qmi_txn_init(&priv->qmi, &txn,
656 			   wlfw_cal_report_resp_msg_v01_ei, resp);
657 	if (ret < 0) {
658 		icnss_qmi_fatal_err("Fail to init txn for cal report req %d\n",
659 				    ret);
660 		goto out;
661 	}
662 
663 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
664 			       QMI_WLFW_CAL_REPORT_REQ_V01,
665 			       WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN,
666 			       wlfw_cal_report_req_msg_v01_ei, req);
667 	if (ret < 0) {
668 		qmi_txn_cancel(&txn);
669 		icnss_qmi_fatal_err("Fail to send cal report req %d\n", ret);
670 		goto out;
671 	}
672 
673 	ret = qmi_txn_wait(&txn,
674 			   priv->ctrl_params.qmi_timeout);
675 
676 	if (ret < 0) {
677 		icnss_qmi_fatal_err("Cal report wait failed with ret %d\n",
678 				    ret);
679 		goto out;
680 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
681 		icnss_qmi_fatal_err("QMI cal report request rejected, result:%d error:%d\n",
682 				    resp->resp.result, resp->resp.error);
683 		ret = -resp->resp.result;
684 		goto out;
685 	}
686 
687 	kfree(resp);
688 	kfree(req);
689 
690 	return 0;
691 
692 out:
693 	return ret;
694 }
695 
696 int wlfw_cap_send_sync_msg(struct icnss_priv *priv)
697 {
698 	int ret;
699 	struct wlfw_cap_req_msg_v01 *req;
700 	struct wlfw_cap_resp_msg_v01 *resp;
701 	struct qmi_txn txn;
702 
703 	if (!priv)
704 		return -ENODEV;
705 
706 	icnss_pr_dbg("Sending target capability message, state: 0x%lx\n",
707 		     priv->state);
708 
709 	req = kzalloc(sizeof(*req), GFP_KERNEL);
710 	if (!req)
711 		return -ENOMEM;
712 
713 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
714 	if (!resp) {
715 		kfree(req);
716 		return -ENOMEM;
717 	}
718 
719 	priv->stats.cap_req++;
720 
721 	ret = qmi_txn_init(&priv->qmi, &txn, wlfw_cap_resp_msg_v01_ei, resp);
722 	if (ret < 0) {
723 		icnss_qmi_fatal_err("Fail to init txn for Capability resp %d\n",
724 				    ret);
725 		goto out;
726 	}
727 
728 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
729 			       QMI_WLFW_CAP_REQ_V01,
730 			       WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN,
731 			       wlfw_cap_req_msg_v01_ei, req);
732 	if (ret < 0) {
733 		qmi_txn_cancel(&txn);
734 		icnss_qmi_fatal_err("Fail to send Capability req %d\n", ret);
735 		goto out;
736 	}
737 
738 	ret = qmi_txn_wait(&txn,
739 			   priv->ctrl_params.qmi_timeout +
740 			   msecs_to_jiffies(priv->wlan_en_delay_ms));
741 	if (ret < 0) {
742 		icnss_qmi_fatal_err("Capability resp wait failed with ret %d\n",
743 				    ret);
744 		goto out;
745 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
746 		ret = -resp->resp.result;
747 		if (resp->resp.error == QMI_ERR_PLAT_CCPM_CLK_INIT_FAILED) {
748 			icnss_pr_err("RF card not present\n");
749 			goto out;
750 		}
751 		icnss_qmi_fatal_err(
752 			"QMI Capability request rejected, result:%d error:%d\n",
753 			resp->resp.result, resp->resp.error);
754 		goto out;
755 	}
756 
757 	priv->stats.cap_resp++;
758 
759 	if (resp->chip_info_valid) {
760 		priv->chip_info.chip_id = resp->chip_info.chip_id;
761 		priv->chip_info.chip_family = resp->chip_info.chip_family;
762 	}
763 	if (resp->board_info_valid)
764 		priv->board_id = resp->board_info.board_id;
765 	else
766 		priv->board_id = 0xFF;
767 	if (resp->soc_info_valid)
768 		priv->soc_id = resp->soc_info.soc_id;
769 	if (resp->fw_version_info_valid) {
770 		priv->fw_version_info.fw_version =
771 			resp->fw_version_info.fw_version;
772 		strlcpy(priv->fw_version_info.fw_build_timestamp,
773 				resp->fw_version_info.fw_build_timestamp,
774 				WLFW_MAX_TIMESTAMP_LEN + 1);
775 	}
776 
777 	if (resp->voltage_mv_valid) {
778 		priv->cpr_info.voltage = resp->voltage_mv;
779 		icnss_pr_dbg("Voltage for CPR: %dmV\n",
780 			    priv->cpr_info.voltage);
781 		icnss_update_cpr_info(priv);
782 	}
783 
784 	if (resp->fw_build_id_valid)
785 		strlcpy(priv->fw_build_id, resp->fw_build_id,
786 			QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1);
787 
788 	if (resp->rd_card_chain_cap_valid) {
789 		priv->rd_card_chain_cap = (enum icnss_rd_card_chain_cap)resp->rd_card_chain_cap;
790 		if (resp->rd_card_chain_cap == WLFW_RD_CARD_CHAIN_CAP_1x1_V01)
791 			priv->is_chain1_supported = false;
792 	}
793 
794 	if (resp->foundry_name_valid)
795 		priv->foundry_name = resp->foundry_name[0];
796 	else if (resp->chip_info_valid && priv->chip_info.chip_id == UMC_CHIP_ID)
797 		priv->foundry_name = 'u';
798 
799 	if (resp->he_channel_width_cap_valid)
800 		priv->phy_he_channel_width_cap =
801 			(enum icnss_phy_he_channel_width_cap)resp->he_channel_width_cap;
802 
803 	if (resp->phy_qam_cap_valid)
804 		priv->phy_qam_cap = (enum icnss_phy_qam_cap)resp->phy_qam_cap;
805 
806 	icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x",
807 		     priv->chip_info.chip_id, priv->chip_info.chip_family,
808 		     priv->board_id, priv->soc_id);
809 
810 	icnss_pr_dbg("fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s",
811 		     priv->fw_version_info.fw_version,
812 		     priv->fw_version_info.fw_build_timestamp,
813 		     priv->fw_build_id);
814 
815 	icnss_pr_dbg("RD card chain cap: %d, PHY HE channel width cap: %d, PHY QAM cap: %d",
816 		     priv->rd_card_chain_cap, priv->phy_he_channel_width_cap,
817 		     priv->phy_qam_cap);
818 
819 	kfree(resp);
820 	kfree(req);
821 	return 0;
822 
823 out:
824 	kfree(resp);
825 	kfree(req);
826 	priv->stats.cap_err++;
827 	return ret;
828 }
829 
830 int icnss_qmi_get_dms_mac(struct icnss_priv *priv)
831 {
832 	struct dms_get_mac_address_req_msg_v01 req;
833 	struct dms_get_mac_address_resp_msg_v01 resp;
834 	struct qmi_txn txn;
835 	int ret = 0;
836 
837 	if  (!test_bit(ICNSS_QMI_DMS_CONNECTED, &priv->state)) {
838 		icnss_pr_err("DMS QMI connection not established\n");
839 		return -EAGAIN;
840 	}
841 	icnss_pr_dbg("Requesting DMS MAC address");
842 
843 	memset(&resp, 0, sizeof(resp));
844 	ret = qmi_txn_init(&priv->qmi_dms, &txn,
845 			   dms_get_mac_address_resp_msg_v01_ei, &resp);
846 	if (ret < 0) {
847 		icnss_pr_err("Failed to initialize txn for dms, err: %d\n",
848 			     ret);
849 		goto out;
850 	}
851 	req.device = DMS_DEVICE_MAC_WLAN_V01;
852 	ret = qmi_send_request(&priv->qmi_dms, NULL, &txn,
853 			       QMI_DMS_GET_MAC_ADDRESS_REQ_V01,
854 			       DMS_GET_MAC_ADDRESS_REQ_MSG_V01_MAX_MSG_LEN,
855 			       dms_get_mac_address_req_msg_v01_ei, &req);
856 	if (ret < 0) {
857 		qmi_txn_cancel(&txn);
858 		icnss_pr_err("Failed to send QMI_DMS_GET_MAC_ADDRESS_REQ_V01, err: %d\n",
859 			     ret);
860 		goto out;
861 	}
862 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
863 	if (ret < 0) {
864 		icnss_pr_err("Failed to wait for QMI_DMS_GET_MAC_ADDRESS_RESP_V01, err: %d\n",
865 			     ret);
866 		goto out;
867 	}
868 
869 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
870 		if (resp.resp.error == DMS_MAC_NOT_PROVISIONED) {
871 			icnss_pr_err("NV MAC address is not provisioned");
872 			priv->dms.nv_mac_not_prov = 1;
873 		} else {
874 			icnss_pr_err("QMI_DMS_GET_MAC_ADDRESS_REQ_V01 failed, result: %d, err: %d\n",
875 				     resp.resp.result, resp.resp.error);
876 		}
877 		ret = -resp.resp.result;
878 		goto out;
879 	}
880 	if (!resp.mac_address_valid ||
881 	    resp.mac_address_len != QMI_WLFW_MAC_ADDR_SIZE_V01) {
882 		icnss_pr_err("Invalid MAC address received from DMS\n");
883 		priv->dms.mac_valid = false;
884 		goto out;
885 	}
886 	priv->dms.mac_valid = true;
887 	memcpy(priv->dms.mac, resp.mac_address, QMI_WLFW_MAC_ADDR_SIZE_V01);
888 	icnss_pr_info("Received DMS MAC: [%pM]\n", priv->dms.mac);
889 out:
890 	return ret;
891 }
892 
893 int icnss_wlfw_wlan_mac_req_send_sync(struct icnss_priv *priv,
894 				      u8 *mac, u32 mac_len)
895 {
896 	struct wlfw_mac_addr_req_msg_v01 req;
897 	struct wlfw_mac_addr_resp_msg_v01 resp = {0};
898 	struct qmi_txn txn;
899 	int ret;
900 
901 	if (!priv || !mac || mac_len != QMI_WLFW_MAC_ADDR_SIZE_V01)
902 		return -EINVAL;
903 
904 	ret = qmi_txn_init(&priv->qmi, &txn,
905 			   wlfw_mac_addr_resp_msg_v01_ei, &resp);
906 	if (ret < 0) {
907 		icnss_pr_err("Failed to initialize txn for mac req, err: %d\n",
908 			     ret);
909 		ret = -EIO;
910 		goto out;
911 	}
912 
913 	icnss_pr_dbg("Sending WLAN mac req [%pM], state: 0x%lx\n",
914 			     mac, priv->state);
915 	memcpy(req.mac_addr, mac, mac_len);
916 	req.mac_addr_valid = 1;
917 
918 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
919 			       QMI_WLFW_MAC_ADDR_REQ_V01,
920 			       WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN,
921 			       wlfw_mac_addr_req_msg_v01_ei, &req);
922 	if (ret < 0) {
923 		qmi_txn_cancel(&txn);
924 		icnss_pr_err("Failed to send mac req, err: %d\n", ret);
925 		ret = -EIO;
926 		goto out;
927 	}
928 
929 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
930 	if (ret < 0) {
931 		icnss_pr_err("Failed to wait for resp of mac req, err: %d\n",
932 			     ret);
933 		ret = -EIO;
934 		goto out;
935 	}
936 
937 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
938 		icnss_pr_err("WLAN mac req failed, result: %d\n",
939 			     resp.resp.result);
940 		ret = -resp.resp.result;
941 	}
942 out:
943 	return ret;
944 }
945 
946 static int icnss_dms_connect_to_server(struct icnss_priv *priv,
947 				      unsigned int node, unsigned int port)
948 {
949 	struct qmi_handle *qmi_dms = &priv->qmi_dms;
950 	struct sockaddr_qrtr sq = {0};
951 	int ret = 0;
952 
953 	sq.sq_family = AF_QIPCRTR;
954 	sq.sq_node = node;
955 	sq.sq_port = port;
956 
957 	ret = kernel_connect(qmi_dms->sock, (struct sockaddr *)&sq,
958 			     sizeof(sq), 0);
959 	if (ret < 0) {
960 		icnss_pr_err("Failed to connect to QMI DMS remote service Node: %d Port: %d\n",
961 			     node, port);
962 		goto out;
963 	}
964 
965 	set_bit(ICNSS_QMI_DMS_CONNECTED, &priv->state);
966 	icnss_pr_info("QMI DMS service connected, state: 0x%lx\n",
967 		      priv->state);
968 out:
969 	return ret;
970 }
971 
972 static int dms_new_server(struct qmi_handle *qmi_dms,
973 			  struct qmi_service *service)
974 {
975 	struct icnss_priv *priv =
976 		container_of(qmi_dms, struct icnss_priv, qmi_dms);
977 
978 	if (!service)
979 		return -EINVAL;
980 
981 	return icnss_dms_connect_to_server(priv, service->node,
982 					   service->port);
983 }
984 
985 static void dms_del_server(struct qmi_handle *qmi_dms,
986 			   struct qmi_service *service)
987 {
988 	struct icnss_priv *priv =
989 		container_of(qmi_dms, struct icnss_priv, qmi_dms);
990 
991 	clear_bit(ICNSS_QMI_DMS_CONNECTED, &priv->state);
992 	icnss_pr_info("QMI DMS service disconnected, state: 0x%lx\n",
993 		      priv->state);
994 }
995 
996 static struct qmi_ops qmi_dms_ops = {
997 	.new_server = dms_new_server,
998 	.del_server = dms_del_server,
999 };
1000 
1001 int icnss_dms_init(struct icnss_priv *priv)
1002 {
1003 	int ret = 0;
1004 
1005 	ret = qmi_handle_init(&priv->qmi_dms, DMS_QMI_MAX_MSG_LEN,
1006 			      &qmi_dms_ops, NULL);
1007 	if (ret < 0) {
1008 		icnss_pr_err("Failed to initialize DMS handle, err: %d\n", ret);
1009 		goto out;
1010 	}
1011 
1012 	ret = qmi_add_lookup(&priv->qmi_dms, DMS_SERVICE_ID_V01,
1013 			     DMS_SERVICE_VERS_V01, 0);
1014 	if (ret < 0)
1015 		icnss_pr_err("Failed to add DMS lookup, err: %d\n", ret);
1016 out:
1017 	return ret;
1018 }
1019 
1020 void icnss_dms_deinit(struct icnss_priv *priv)
1021 {
1022 	qmi_handle_release(&priv->qmi_dms);
1023 }
1024 
1025 static int icnss_get_bdf_file_name(struct icnss_priv *priv,
1026 				   u32 bdf_type, char *filename,
1027 				   u32 filename_len)
1028 {
1029 	char filename_tmp[ICNSS_MAX_FILE_NAME];
1030 	char foundry_specific_filename[ICNSS_MAX_FILE_NAME];
1031 	int ret = 0;
1032 
1033 	switch (bdf_type) {
1034 	case ICNSS_BDF_ELF:
1035 		if (priv->board_id == 0xFF)
1036 			snprintf(filename_tmp, filename_len, ELF_BDF_FILE_NAME);
1037 		else if (priv->board_id < 0xFF)
1038 			snprintf(filename_tmp, filename_len,
1039 				 ELF_BDF_FILE_NAME_PREFIX "%02x",
1040 				 priv->board_id);
1041 		else
1042 			snprintf(filename_tmp, filename_len,
1043 				 BDF_FILE_NAME_PREFIX "%02x.e%02x",
1044 				 priv->board_id >> 8 & 0xFF,
1045 				 priv->board_id & 0xFF);
1046 		break;
1047 	case ICNSS_BDF_BIN:
1048 		if (priv->board_id == 0xFF)
1049 			snprintf(filename_tmp, filename_len, BIN_BDF_FILE_NAME);
1050 		else if (priv->board_id >= WLAN_BOARD_ID_INDEX)
1051 			snprintf(filename_tmp, filename_len,
1052 				 BIN_BDF_FILE_NAME_PREFIX "%03x",
1053 				 priv->board_id);
1054 		else
1055 			snprintf(filename_tmp, filename_len,
1056 				 BIN_BDF_FILE_NAME_PREFIX "b%02x",
1057 				 priv->board_id);
1058 		if (priv->foundry_name) {
1059 			strlcpy(foundry_specific_filename, filename_tmp, ICNSS_MAX_FILE_NAME);
1060 			memmove(foundry_specific_filename + BDWLAN_SIZE + 1,
1061 				foundry_specific_filename + BDWLAN_SIZE,
1062 				BDWLAN_SIZE - 1);
1063 			foundry_specific_filename[BDWLAN_SIZE] = priv->foundry_name;
1064 			foundry_specific_filename[ICNSS_MAX_FILE_NAME - 1] = '\0';
1065 			strlcpy(filename_tmp, foundry_specific_filename, ICNSS_MAX_FILE_NAME);
1066 		}
1067 		break;
1068 	case ICNSS_BDF_REGDB:
1069 		snprintf(filename_tmp, filename_len, REGDB_FILE_NAME);
1070 		break;
1071 	default:
1072 		icnss_pr_err("Invalid BDF type: %d\n",
1073 			     priv->ctrl_params.bdf_type);
1074 		ret = -EINVAL;
1075 		break;
1076 	}
1077 
1078 	if (!ret)
1079 		icnss_add_fw_prefix_name(priv, filename, filename_tmp);
1080 
1081 	return ret;
1082 }
1083 
1084 static char *icnss_bdf_type_to_str(enum icnss_bdf_type bdf_type)
1085 {
1086 	switch (bdf_type) {
1087 	case ICNSS_BDF_BIN:
1088 		return "BDF";
1089 	case ICNSS_BDF_ELF:
1090 		return "BDF";
1091 	case ICNSS_BDF_REGDB:
1092 		return "REGDB";
1093 	default:
1094 		return "UNKNOWN";
1095 	}
1096 };
1097 
1098 int icnss_wlfw_bdf_dnld_send_sync(struct icnss_priv *priv, u32 bdf_type)
1099 {
1100 	struct wlfw_bdf_download_req_msg_v01 *req;
1101 	struct wlfw_bdf_download_resp_msg_v01 *resp;
1102 	struct qmi_txn txn;
1103 	char filename[ICNSS_MAX_FILE_NAME];
1104 	const struct firmware *fw_entry = NULL;
1105 	const u8 *temp;
1106 	unsigned int remaining;
1107 	int ret = 0;
1108 
1109 	icnss_pr_dbg("Sending %s download message, state: 0x%lx, type: %d\n",
1110 		     icnss_bdf_type_to_str(bdf_type), priv->state, bdf_type);
1111 
1112 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1113 	if (!req)
1114 		return -ENOMEM;
1115 
1116 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1117 	if (!resp) {
1118 		kfree(req);
1119 		return -ENOMEM;
1120 	}
1121 
1122 	ret = icnss_get_bdf_file_name(priv, bdf_type,
1123 				      filename, sizeof(filename));
1124 	if (ret)
1125 		goto err_req_fw;
1126 
1127 	ret = firmware_request_nowarn(&fw_entry, filename, &priv->pdev->dev);
1128 	if (ret) {
1129 		icnss_pr_err("Failed to load %s: %s ret:%d\n",
1130 			     icnss_bdf_type_to_str(bdf_type), filename, ret);
1131 		goto err_req_fw;
1132 	}
1133 
1134 	temp = fw_entry->data;
1135 	remaining = fw_entry->size;
1136 
1137 	icnss_pr_dbg("Downloading %s: %s, size: %u\n",
1138 		     icnss_bdf_type_to_str(bdf_type), filename, remaining);
1139 
1140 	while (remaining) {
1141 		req->valid = 1;
1142 		req->file_id_valid = 1;
1143 		req->file_id = priv->board_id;
1144 		req->total_size_valid = 1;
1145 		req->total_size = fw_entry->size;
1146 		req->seg_id_valid = 1;
1147 		req->data_valid = 1;
1148 		req->end_valid = 1;
1149 		req->bdf_type_valid = 1;
1150 		req->bdf_type = bdf_type;
1151 
1152 		if (remaining > QMI_WLFW_MAX_DATA_SIZE_V01) {
1153 			req->data_len = QMI_WLFW_MAX_DATA_SIZE_V01;
1154 		} else {
1155 			req->data_len = remaining;
1156 			req->end = 1;
1157 		}
1158 
1159 		memcpy(req->data, temp, req->data_len);
1160 
1161 		ret = qmi_txn_init(&priv->qmi, &txn,
1162 				   wlfw_bdf_download_resp_msg_v01_ei, resp);
1163 		if (ret < 0) {
1164 			icnss_pr_err("Failed to initialize txn for %s download request, err: %d\n",
1165 				     icnss_bdf_type_to_str(bdf_type), ret);
1166 			goto err_send;
1167 		}
1168 
1169 		ret = qmi_send_request
1170 			(&priv->qmi, NULL, &txn,
1171 			 QMI_WLFW_BDF_DOWNLOAD_REQ_V01,
1172 			 WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
1173 			 wlfw_bdf_download_req_msg_v01_ei, req);
1174 		if (ret < 0) {
1175 			qmi_txn_cancel(&txn);
1176 			icnss_pr_err("Failed to send respond %s download request, err: %d\n",
1177 				     icnss_bdf_type_to_str(bdf_type), ret);
1178 			goto err_send;
1179 		}
1180 
1181 		ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1182 		if (ret < 0) {
1183 			icnss_pr_err("Failed to wait for response of %s download request, err: %d\n",
1184 				     icnss_bdf_type_to_str(bdf_type), ret);
1185 			goto err_send;
1186 		}
1187 
1188 		if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1189 			icnss_pr_err("%s download request failed, result: %d, err: %d\n",
1190 				     icnss_bdf_type_to_str(bdf_type), resp->resp.result,
1191 				     resp->resp.error);
1192 			ret = -resp->resp.result;
1193 			goto err_send;
1194 		}
1195 
1196 		remaining -= req->data_len;
1197 		temp += req->data_len;
1198 		req->seg_id++;
1199 	}
1200 
1201 	release_firmware(fw_entry);
1202 
1203 	kfree(req);
1204 	kfree(resp);
1205 	return 0;
1206 
1207 err_send:
1208 	release_firmware(fw_entry);
1209 err_req_fw:
1210 	if (bdf_type != ICNSS_BDF_REGDB)
1211 		ICNSS_QMI_ASSERT();
1212 	kfree(req);
1213 	kfree(resp);
1214 	return ret;
1215 }
1216 
1217 int icnss_wlfw_qdss_data_send_sync(struct icnss_priv *priv, char *file_name,
1218 				   u32 total_size)
1219 {
1220 	int ret = 0;
1221 	struct wlfw_qdss_trace_data_req_msg_v01 *req;
1222 	struct wlfw_qdss_trace_data_resp_msg_v01 *resp;
1223 	unsigned char *p_qdss_trace_data_temp, *p_qdss_trace_data = NULL;
1224 	unsigned int remaining;
1225 	struct qmi_txn txn;
1226 
1227 	icnss_pr_dbg("%s", __func__);
1228 
1229 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1230 	if (!req)
1231 		return -ENOMEM;
1232 
1233 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1234 	if (!resp) {
1235 		kfree(req);
1236 		return -ENOMEM;
1237 	}
1238 
1239 	p_qdss_trace_data = kzalloc(total_size, GFP_KERNEL);
1240 	if (!p_qdss_trace_data) {
1241 		ret = ENOMEM;
1242 		goto end;
1243 	}
1244 
1245 	remaining = total_size;
1246 	p_qdss_trace_data_temp = p_qdss_trace_data;
1247 	while (remaining && resp->end == 0) {
1248 		ret = qmi_txn_init(&priv->qmi, &txn,
1249 				   wlfw_qdss_trace_data_resp_msg_v01_ei, resp);
1250 
1251 		if (ret < 0) {
1252 			icnss_pr_err("Fail to init txn for QDSS trace resp %d\n",
1253 				     ret);
1254 			goto fail;
1255 		}
1256 
1257 		ret = qmi_send_request
1258 			(&priv->qmi, NULL, &txn,
1259 			 QMI_WLFW_QDSS_TRACE_DATA_REQ_V01,
1260 			 WLFW_QDSS_TRACE_DATA_REQ_MSG_V01_MAX_MSG_LEN,
1261 			 wlfw_qdss_trace_data_req_msg_v01_ei, req);
1262 
1263 		if (ret < 0) {
1264 			qmi_txn_cancel(&txn);
1265 			icnss_pr_err("Fail to send QDSS trace data req %d\n",
1266 				     ret);
1267 			goto fail;
1268 		}
1269 
1270 		ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1271 
1272 		if (ret < 0) {
1273 			icnss_pr_err("QDSS trace resp wait failed with rc %d\n",
1274 				     ret);
1275 			goto fail;
1276 		} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1277 			icnss_pr_err("QMI QDSS trace request rejected, result:%d error:%d\n",
1278 				     resp->resp.result, resp->resp.error);
1279 				     ret = -resp->resp.result;
1280 			goto fail;
1281 		} else {
1282 			ret = 0;
1283 		}
1284 
1285 		icnss_pr_dbg("%s: response total size  %d data len %d",
1286 			     __func__, resp->total_size, resp->data_len);
1287 
1288 		if ((resp->total_size_valid == 1 &&
1289 		     resp->total_size == total_size) &&
1290 		    (resp->seg_id_valid == 1 && resp->seg_id == req->seg_id) &&
1291 		    (resp->data_valid == 1 &&
1292 		     resp->data_len <= QMI_WLFW_MAX_DATA_SIZE_V01) &&
1293 		    resp->data_len <= remaining) {
1294 			memcpy(p_qdss_trace_data_temp,
1295 			       resp->data, resp->data_len);
1296 		} else {
1297 			icnss_pr_err("%s: Unmatched qdss trace data, Expect total_size %u, seg_id %u, Recv total_size_valid %u, total_size %u, seg_id_valid %u, seg_id %u, data_len_valid %u, data_len %u",
1298 				     __func__,
1299 				     total_size, req->seg_id,
1300 				     resp->total_size_valid,
1301 				     resp->total_size,
1302 				     resp->seg_id_valid,
1303 				     resp->seg_id,
1304 				     resp->data_valid,
1305 				     resp->data_len);
1306 			ret = -EINVAL;
1307 			goto fail;
1308 		}
1309 
1310 		remaining -= resp->data_len;
1311 		p_qdss_trace_data_temp += resp->data_len;
1312 		req->seg_id++;
1313 	}
1314 
1315 	if (remaining == 0 && (resp->end_valid && resp->end)) {
1316 		ret = icnss_genl_send_msg(p_qdss_trace_data,
1317 					  ICNSS_GENL_MSG_TYPE_QDSS, file_name,
1318 					  total_size);
1319 		if (ret < 0) {
1320 			icnss_pr_err("Fail to save QDSS trace data: %d\n",
1321 				     ret);
1322 		ret = -EINVAL;
1323 		}
1324 	} else {
1325 		icnss_pr_err("%s: QDSS trace file corrupted: remaining %u, end_valid %u, end %u",
1326 			     __func__,
1327 			     remaining, resp->end_valid, resp->end);
1328 		ret = -EINVAL;
1329 	}
1330 
1331 fail:
1332 	kfree(p_qdss_trace_data);
1333 
1334 end:
1335 	kfree(req);
1336 	kfree(resp);
1337 	return ret;
1338 }
1339 
1340 int icnss_wlfw_qdss_dnld_send_sync(struct icnss_priv *priv)
1341 {
1342 	struct wlfw_qdss_trace_config_download_req_msg_v01 *req;
1343 	struct wlfw_qdss_trace_config_download_resp_msg_v01 *resp;
1344 	struct qmi_txn txn;
1345 	char filename[ICNSS_MAX_FILE_NAME];
1346 	const struct firmware *fw_entry = NULL;
1347 	const u8 *temp;
1348 	unsigned int remaining;
1349 	int ret = 0;
1350 
1351 	icnss_pr_dbg("Sending QDSS config download message, state: 0x%lx\n",
1352 		     priv->state);
1353 
1354 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1355 	if (!req)
1356 		return -ENOMEM;
1357 
1358 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1359 	if (!resp) {
1360 		kfree(req);
1361 		return -ENOMEM;
1362 	}
1363 
1364 	icnss_add_fw_prefix_name(priv, filename, QDSS_TRACE_CONFIG_FILE);
1365 	ret = firmware_request_nowarn(&fw_entry, filename,
1366 				      &priv->pdev->dev);
1367 	if (ret) {
1368 		icnss_pr_err("Failed to load QDSS: %s ret:%d\n",
1369 			     filename, ret);
1370 		goto err_req_fw;
1371 	}
1372 
1373 	temp = fw_entry->data;
1374 	remaining = fw_entry->size;
1375 
1376 	icnss_pr_dbg("Downloading QDSS: %s, size: %u\n",
1377 		     filename, remaining);
1378 
1379 	while (remaining) {
1380 		req->total_size_valid = 1;
1381 		req->total_size = remaining;
1382 		req->seg_id_valid = 1;
1383 		req->data_valid = 1;
1384 		req->end_valid = 1;
1385 
1386 		if (remaining > QMI_WLFW_MAX_DATA_SIZE_V01) {
1387 			req->data_len = QMI_WLFW_MAX_DATA_SIZE_V01;
1388 		} else {
1389 			req->data_len = remaining;
1390 			req->end = 1;
1391 		}
1392 
1393 		memcpy(req->data, temp, req->data_len);
1394 
1395 		ret = qmi_txn_init
1396 			(&priv->qmi, &txn,
1397 			 wlfw_qdss_trace_config_download_resp_msg_v01_ei,
1398 			 resp);
1399 		if (ret < 0) {
1400 			icnss_pr_err("Failed to initialize txn for QDSS download request, err: %d\n",
1401 				     ret);
1402 			goto err_send;
1403 		}
1404 
1405 		ret = qmi_send_request
1406 		      (&priv->qmi, NULL, &txn,
1407 		       QMI_WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_V01,
1408 		       WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
1409 		       wlfw_qdss_trace_config_download_req_msg_v01_ei, req);
1410 		if (ret < 0) {
1411 			qmi_txn_cancel(&txn);
1412 			icnss_pr_err("Failed to send respond QDSS download request, err: %d\n",
1413 				     ret);
1414 			goto err_send;
1415 		}
1416 
1417 		ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1418 		if (ret < 0) {
1419 			icnss_pr_err("Failed to wait for response of QDSS download request, err: %d\n",
1420 				     ret);
1421 			goto err_send;
1422 		}
1423 
1424 		if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1425 			icnss_pr_err("QDSS download request failed, result: %d, err: %d\n",
1426 				     resp->resp.result, resp->resp.error);
1427 			ret = -resp->resp.result;
1428 			goto err_send;
1429 		}
1430 
1431 		remaining -= req->data_len;
1432 		temp += req->data_len;
1433 		req->seg_id++;
1434 	}
1435 
1436 	release_firmware(fw_entry);
1437 	kfree(req);
1438 	kfree(resp);
1439 	return 0;
1440 
1441 err_send:
1442 	release_firmware(fw_entry);
1443 err_req_fw:
1444 
1445 	kfree(req);
1446 	kfree(resp);
1447 	return ret;
1448 }
1449 
1450 int wlfw_wlan_mode_send_sync_msg(struct icnss_priv *priv,
1451 		enum wlfw_driver_mode_enum_v01 mode)
1452 {
1453 	int ret;
1454 	struct wlfw_wlan_mode_req_msg_v01 *req;
1455 	struct wlfw_wlan_mode_resp_msg_v01 *resp;
1456 	struct qmi_txn txn;
1457 
1458 	if (!priv)
1459 		return -ENODEV;
1460 
1461 	/* During recovery do not send mode request for WLAN OFF as
1462 	 * FW not able to process it.
1463 	 */
1464 	if (test_bit(ICNSS_PD_RESTART, &priv->state) &&
1465 	    mode == QMI_WLFW_OFF_V01)
1466 		return 0;
1467 
1468 	if (!test_bit(ICNSS_MODE_ON, &priv->state) &&
1469 	    mode == QMI_WLFW_OFF_V01)
1470 		return 0;
1471 
1472 	icnss_pr_dbg("Sending Mode request, state: 0x%lx, mode: %d\n",
1473 		     priv->state, mode);
1474 
1475 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1476 	if (!req)
1477 		return -ENOMEM;
1478 
1479 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1480 	if (!resp) {
1481 		kfree(req);
1482 		return -ENOMEM;
1483 	}
1484 
1485 	req->mode = mode;
1486 	req->hw_debug_valid = 1;
1487 	req->hw_debug = !!test_bit(HW_DEBUG_ENABLE, &priv->ctrl_params.quirks);
1488 
1489 	if (priv->wlan_en_delay_ms >= 100) {
1490 		icnss_pr_dbg("Setting WLAN_EN delay: %d ms\n",
1491 			     priv->wlan_en_delay_ms);
1492 		req->wlan_en_delay_valid = 1;
1493 		req->wlan_en_delay = priv->wlan_en_delay_ms;
1494 	}
1495 
1496 	priv->stats.mode_req++;
1497 
1498 	ret = qmi_txn_init(&priv->qmi, &txn,
1499 			   wlfw_wlan_mode_resp_msg_v01_ei, resp);
1500 	if (ret < 0) {
1501 		icnss_qmi_fatal_err("Fail to init txn for Mode resp %d\n", ret);
1502 		goto out;
1503 	}
1504 
1505 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
1506 			       QMI_WLFW_WLAN_MODE_REQ_V01,
1507 			       WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN,
1508 			       wlfw_wlan_mode_req_msg_v01_ei, req);
1509 	if (ret < 0) {
1510 		qmi_txn_cancel(&txn);
1511 		icnss_qmi_fatal_err("Fail to send Mode req %d\n", ret);
1512 		goto out;
1513 	}
1514 
1515 	ret = qmi_txn_wait(&txn,
1516 			   priv->ctrl_params.qmi_timeout +
1517 			   msecs_to_jiffies(priv->wlan_en_delay_ms));
1518 	if (ret < 0) {
1519 		icnss_qmi_fatal_err("Mode resp wait failed with ret %d\n", ret);
1520 		goto out;
1521 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1522 		icnss_qmi_fatal_err(
1523 			"QMI Mode request rejected, result:%d error:%d\n",
1524 			resp->resp.result, resp->resp.error);
1525 		ret = -resp->resp.result;
1526 		goto out;
1527 	}
1528 
1529 	priv->stats.mode_resp++;
1530 
1531 	if (mode == QMI_WLFW_OFF_V01) {
1532 		icnss_pr_dbg("Clear mode on 0x%lx, mode: %d\n",
1533 			     priv->state, mode);
1534 		clear_bit(ICNSS_MODE_ON, &priv->state);
1535 	} else {
1536 		icnss_pr_dbg("Set mode on 0x%lx, mode: %d\n",
1537 			     priv->state, mode);
1538 		set_bit(ICNSS_MODE_ON, &priv->state);
1539 	}
1540 
1541 	kfree(resp);
1542 	kfree(req);
1543 	return 0;
1544 
1545 out:
1546 	kfree(resp);
1547 	kfree(req);
1548 	priv->stats.mode_req_err++;
1549 	return ret;
1550 }
1551 
1552 static int wlfw_send_qdss_trace_mode_req
1553 		(struct icnss_priv *priv,
1554 		 enum wlfw_qdss_trace_mode_enum_v01 mode,
1555 		 unsigned long long option)
1556 {
1557 	int rc = 0;
1558 	int tmp = 0;
1559 	struct wlfw_qdss_trace_mode_req_msg_v01 *req;
1560 	struct wlfw_qdss_trace_mode_resp_msg_v01 *resp;
1561 	struct qmi_txn txn;
1562 
1563 	if (!priv)
1564 		return -ENODEV;
1565 
1566 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1567 	if (!req)
1568 		return -ENOMEM;
1569 
1570 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1571 	if (!resp) {
1572 		kfree(req);
1573 		return -ENOMEM;
1574 	}
1575 
1576 	req->mode_valid = 1;
1577 	req->mode = mode;
1578 	req->option_valid = 1;
1579 	req->option = option;
1580 
1581 	tmp = priv->hw_trc_override;
1582 
1583 	req->hw_trc_disable_override_valid = 1;
1584 	req->hw_trc_disable_override =
1585 	(tmp > QMI_PARAM_DISABLE_V01 ? QMI_PARAM_DISABLE_V01 :
1586 		 (tmp < 0 ? QMI_PARAM_INVALID_V01 : tmp));
1587 
1588 	icnss_pr_dbg("%s: mode %u, option %llu, hw_trc_disable_override: %u",
1589 		     __func__, mode, option, req->hw_trc_disable_override);
1590 
1591 	rc = qmi_txn_init(&priv->qmi, &txn,
1592 			  wlfw_qdss_trace_mode_resp_msg_v01_ei, resp);
1593 	if (rc < 0) {
1594 		icnss_qmi_fatal_err("Fail to init txn for QDSS Mode resp %d\n",
1595 				    rc);
1596 		goto out;
1597 	}
1598 
1599 	rc = qmi_send_request(&priv->qmi, NULL, &txn,
1600 			      QMI_WLFW_QDSS_TRACE_MODE_REQ_V01,
1601 			      WLFW_QDSS_TRACE_MODE_REQ_MSG_V01_MAX_MSG_LEN,
1602 			      wlfw_qdss_trace_mode_req_msg_v01_ei, req);
1603 	if (rc < 0) {
1604 		qmi_txn_cancel(&txn);
1605 		icnss_qmi_fatal_err("Fail to send QDSS Mode req %d\n", rc);
1606 		goto out;
1607 	}
1608 
1609 	rc = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1610 	if (rc < 0) {
1611 		icnss_qmi_fatal_err("QDSS Mode resp wait failed with rc %d\n",
1612 				    rc);
1613 		goto out;
1614 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1615 		icnss_qmi_fatal_err(
1616 			"QMI QDSS Mode request rejected, result:%d error:%d\n",
1617 			resp->resp.result, resp->resp.error);
1618 		rc = -resp->resp.result;
1619 		goto out;
1620 	}
1621 
1622 out:
1623 	kfree(resp);
1624 	kfree(req);
1625 	return rc;
1626 }
1627 
1628 int wlfw_qdss_trace_start(struct icnss_priv *priv)
1629 {
1630 	return wlfw_send_qdss_trace_mode_req(priv,
1631 					     QMI_WLFW_QDSS_TRACE_ON_V01, 0);
1632 }
1633 
1634 int wlfw_qdss_trace_stop(struct icnss_priv *priv, unsigned long long option)
1635 {
1636 	return wlfw_send_qdss_trace_mode_req(priv, QMI_WLFW_QDSS_TRACE_OFF_V01,
1637 					     option);
1638 }
1639 
1640 int wlfw_wlan_cfg_send_sync_msg(struct icnss_priv *priv,
1641 				struct wlfw_wlan_cfg_req_msg_v01 *data)
1642 {
1643 	int ret;
1644 	struct wlfw_wlan_cfg_req_msg_v01 *req;
1645 	struct wlfw_wlan_cfg_resp_msg_v01 *resp;
1646 	struct qmi_txn txn;
1647 
1648 	if (!priv)
1649 		return -ENODEV;
1650 
1651 	icnss_pr_dbg("Sending config request, state: 0x%lx\n", priv->state);
1652 
1653 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1654 	if (!req)
1655 		return -ENOMEM;
1656 
1657 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1658 	if (!resp) {
1659 		kfree(req);
1660 		return -ENOMEM;
1661 	}
1662 
1663 	memcpy(req, data, sizeof(*req));
1664 
1665 	priv->stats.cfg_req++;
1666 
1667 	ret = qmi_txn_init(&priv->qmi, &txn,
1668 			   wlfw_wlan_cfg_resp_msg_v01_ei, resp);
1669 	if (ret < 0) {
1670 		icnss_qmi_fatal_err("Fail to init txn for Config resp %d\n",
1671 				    ret);
1672 		goto out;
1673 	}
1674 
1675 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
1676 			       QMI_WLFW_WLAN_CFG_REQ_V01,
1677 			       WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN,
1678 			       wlfw_wlan_cfg_req_msg_v01_ei, req);
1679 	if (ret < 0) {
1680 		qmi_txn_cancel(&txn);
1681 		icnss_qmi_fatal_err("Fail to send Config req %d\n", ret);
1682 		goto out;
1683 	}
1684 
1685 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1686 	if (ret < 0) {
1687 		icnss_qmi_fatal_err("Config resp wait failed with ret %d\n",
1688 				    ret);
1689 		goto out;
1690 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1691 		icnss_qmi_fatal_err(
1692 			"QMI Config request rejected, result:%d error:%d\n",
1693 			resp->resp.result, resp->resp.error);
1694 		ret = -resp->resp.result;
1695 		goto out;
1696 	}
1697 
1698 	priv->stats.cfg_resp++;
1699 
1700 	kfree(resp);
1701 	kfree(req);
1702 	return 0;
1703 
1704 out:
1705 	kfree(resp);
1706 	kfree(req);
1707 	priv->stats.cfg_req_err++;
1708 	return ret;
1709 }
1710 
1711 int wlfw_send_modem_shutdown_msg(struct icnss_priv *priv)
1712 {
1713 	int ret;
1714 	struct wlfw_shutdown_req_msg_v01 *req;
1715 	struct wlfw_shutdown_resp_msg_v01 *resp;
1716 	struct qmi_txn txn;
1717 
1718 	if (!priv)
1719 		return -ENODEV;
1720 
1721 	if (test_bit(ICNSS_FW_DOWN, &priv->state))
1722 		return -EINVAL;
1723 
1724 	icnss_pr_dbg("Sending modem shutdown request, state: 0x%lx\n",
1725 		     priv->state);
1726 
1727 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1728 	if (!req)
1729 		return -ENOMEM;
1730 
1731 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1732 	if (!resp) {
1733 		kfree(req);
1734 		return -ENOMEM;
1735 	}
1736 
1737 	req->shutdown_valid = 1;
1738 	req->shutdown = 1;
1739 
1740 	ret = qmi_txn_init(&priv->qmi, &txn,
1741 			   wlfw_shutdown_resp_msg_v01_ei, resp);
1742 
1743 	if (ret < 0) {
1744 		icnss_pr_err("Fail to init txn for shutdown resp %d\n",
1745 			     ret);
1746 		goto out;
1747 	}
1748 
1749 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
1750 			       QMI_WLFW_SHUTDOWN_REQ_V01,
1751 			       WLFW_SHUTDOWN_REQ_MSG_V01_MAX_MSG_LEN,
1752 			       wlfw_shutdown_req_msg_v01_ei, req);
1753 	if (ret < 0) {
1754 		qmi_txn_cancel(&txn);
1755 		icnss_pr_err("Fail to send Shutdown req %d\n", ret);
1756 		goto out;
1757 	}
1758 
1759 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1760 	if (ret < 0) {
1761 		icnss_pr_err("Shutdown resp wait failed with ret %d\n",
1762 			     ret);
1763 		goto out;
1764 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1765 		icnss_pr_err("QMI modem shutdown request rejected result:%d error:%d\n",
1766 			     resp->resp.result, resp->resp.error);
1767 		ret = -resp->resp.result;
1768 		goto out;
1769 	}
1770 
1771 out:
1772 	kfree(resp);
1773 	kfree(req);
1774 	return ret;
1775 }
1776 
1777 int wlfw_ini_send_sync_msg(struct icnss_priv *priv, uint8_t fw_log_mode)
1778 {
1779 	int ret;
1780 	struct wlfw_ini_req_msg_v01 *req;
1781 	struct wlfw_ini_resp_msg_v01 *resp;
1782 	struct qmi_txn txn;
1783 
1784 	if (!priv)
1785 		return -ENODEV;
1786 
1787 	icnss_pr_dbg("Sending ini sync request, state: 0x%lx, fw_log_mode: %d\n",
1788 		     priv->state, fw_log_mode);
1789 
1790 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1791 	if (!req)
1792 		return -ENOMEM;
1793 
1794 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1795 	if (!resp) {
1796 		kfree(req);
1797 		return -ENOMEM;
1798 	}
1799 
1800 	req->enablefwlog_valid = 1;
1801 	req->enablefwlog = fw_log_mode;
1802 
1803 	priv->stats.ini_req++;
1804 
1805 	ret = qmi_txn_init(&priv->qmi, &txn, wlfw_ini_resp_msg_v01_ei, resp);
1806 	if (ret < 0) {
1807 		icnss_qmi_fatal_err("Fail to init txn for INI resp %d\n", ret);
1808 		goto out;
1809 	}
1810 
1811 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
1812 			       QMI_WLFW_INI_REQ_V01,
1813 			       WLFW_INI_REQ_MSG_V01_MAX_MSG_LEN,
1814 			       wlfw_ini_req_msg_v01_ei, req);
1815 	if (ret < 0) {
1816 		qmi_txn_cancel(&txn);
1817 		icnss_qmi_fatal_err("Fail to send INI req %d\n", ret);
1818 		goto out;
1819 	}
1820 
1821 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1822 	if (ret < 0) {
1823 		icnss_qmi_fatal_err("INI resp wait failed with ret %d\n", ret);
1824 		goto out;
1825 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1826 		icnss_qmi_fatal_err(
1827 			"QMI INI request rejected, result:%d error:%d\n",
1828 			resp->resp.result, resp->resp.error);
1829 		ret = -resp->resp.result;
1830 		goto out;
1831 	}
1832 
1833 	priv->stats.ini_resp++;
1834 
1835 	kfree(resp);
1836 	kfree(req);
1837 	return 0;
1838 
1839 out:
1840 	kfree(resp);
1841 	kfree(req);
1842 	priv->stats.ini_req_err++;
1843 	return ret;
1844 }
1845 
1846 int wlfw_athdiag_read_send_sync_msg(struct icnss_priv *priv,
1847 					   uint32_t offset, uint32_t mem_type,
1848 					   uint32_t data_len, uint8_t *data)
1849 {
1850 	int ret;
1851 	struct wlfw_athdiag_read_req_msg_v01 *req;
1852 	struct wlfw_athdiag_read_resp_msg_v01 *resp;
1853 	struct qmi_txn txn;
1854 
1855 	if (!priv)
1856 		return -ENODEV;
1857 
1858 	icnss_pr_dbg("Diag read: state 0x%lx, offset %x, mem_type %x, data_len %u\n",
1859 		     priv->state, offset, mem_type, data_len);
1860 
1861 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1862 	if (!req)
1863 		return -ENOMEM;
1864 
1865 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1866 	if (!resp) {
1867 		kfree(req);
1868 		return  -ENOMEM;
1869 	}
1870 
1871 	req->offset = offset;
1872 	req->mem_type = mem_type;
1873 	req->data_len = data_len;
1874 
1875 	ret = qmi_txn_init(&priv->qmi, &txn,
1876 			   wlfw_athdiag_read_resp_msg_v01_ei, resp);
1877 	if (ret < 0) {
1878 		icnss_pr_err("Fail to init txn for Athdiag Read resp %d\n",
1879 			     ret);
1880 		goto out;
1881 	}
1882 
1883 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
1884 			       QMI_WLFW_ATHDIAG_READ_REQ_V01,
1885 			       WLFW_ATHDIAG_READ_REQ_MSG_V01_MAX_MSG_LEN,
1886 			       wlfw_athdiag_read_req_msg_v01_ei, req);
1887 	if (ret < 0) {
1888 		qmi_txn_cancel(&txn);
1889 		icnss_pr_err("Fail to send Athdiag Read req %d\n", ret);
1890 		goto out;
1891 	}
1892 
1893 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1894 	if (ret < 0) {
1895 		icnss_pr_err("Athdaig Read resp wait failed with ret %d\n",
1896 			     ret);
1897 		goto out;
1898 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1899 		icnss_pr_err("QMI Athdiag Read request rejected, result:%d error:%d\n",
1900 			resp->resp.result, resp->resp.error);
1901 		ret = -resp->resp.result;
1902 		goto out;
1903 	} else {
1904 		ret = 0;
1905 	}
1906 
1907 	if (!resp->data_valid || resp->data_len < data_len) {
1908 		icnss_pr_err("Athdiag read data is invalid, data_valid = %u, data_len = %u\n",
1909 			     resp->data_valid, resp->data_len);
1910 		ret = -EINVAL;
1911 		goto out;
1912 	}
1913 
1914 	memcpy(data, resp->data, resp->data_len);
1915 
1916 out:
1917 	kfree(resp);
1918 	kfree(req);
1919 	return ret;
1920 }
1921 
1922 int wlfw_athdiag_write_send_sync_msg(struct icnss_priv *priv,
1923 					    uint32_t offset, uint32_t mem_type,
1924 					    uint32_t data_len, uint8_t *data)
1925 {
1926 	int ret;
1927 	struct wlfw_athdiag_write_req_msg_v01 *req;
1928 	struct wlfw_athdiag_write_resp_msg_v01 *resp;
1929 	struct qmi_txn txn;
1930 
1931 	if (!priv)
1932 		return -ENODEV;
1933 
1934 	icnss_pr_dbg("Diag write: state 0x%lx, offset %x, mem_type %x, data_len %u, data %pK\n",
1935 		     priv->state, offset, mem_type, data_len, data);
1936 
1937 	req = kzalloc(sizeof(*req), GFP_KERNEL);
1938 	if (!req)
1939 		return -ENOMEM;
1940 
1941 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1942 	if (!resp) {
1943 		kfree(req);
1944 		return -ENOMEM;
1945 	}
1946 
1947 	req->offset = offset;
1948 	req->mem_type = mem_type;
1949 	req->data_len = data_len;
1950 	memcpy(req->data, data, data_len);
1951 
1952 	ret = qmi_txn_init(&priv->qmi, &txn,
1953 			   wlfw_athdiag_write_resp_msg_v01_ei, resp);
1954 	if (ret < 0) {
1955 		icnss_pr_err("Fail to init txn for Athdiag Write resp %d\n",
1956 			     ret);
1957 		goto out;
1958 	}
1959 
1960 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
1961 			       QMI_WLFW_ATHDIAG_WRITE_REQ_V01,
1962 			       WLFW_ATHDIAG_WRITE_REQ_MSG_V01_MAX_MSG_LEN,
1963 			       wlfw_athdiag_write_req_msg_v01_ei, req);
1964 	if (ret < 0) {
1965 		qmi_txn_cancel(&txn);
1966 		icnss_pr_err("Fail to send Athdiag Write req %d\n", ret);
1967 		goto out;
1968 	}
1969 
1970 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
1971 	if (ret < 0) {
1972 		icnss_pr_err("Athdiag Write resp wait failed with ret %d\n",
1973 			     ret);
1974 		goto out;
1975 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1976 		icnss_pr_err("QMI Athdiag Write request rejected, result:%d error:%d\n",
1977 			resp->resp.result, resp->resp.error);
1978 		ret = -resp->resp.result;
1979 		goto out;
1980 	} else {
1981 		ret = 0;
1982 	}
1983 
1984 out:
1985 	kfree(resp);
1986 	kfree(req);
1987 	return ret;
1988 }
1989 
1990 int wlfw_rejuvenate_ack_send_sync_msg(struct icnss_priv *priv)
1991 {
1992 	int ret;
1993 	struct wlfw_rejuvenate_ack_req_msg_v01 *req;
1994 	struct wlfw_rejuvenate_ack_resp_msg_v01 *resp;
1995 	struct qmi_txn txn;
1996 
1997 	if (!priv)
1998 		return -ENODEV;
1999 
2000 	icnss_pr_dbg("Sending rejuvenate ack request, state: 0x%lx\n",
2001 		     priv->state);
2002 
2003 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2004 	if (!req)
2005 		return -ENOMEM;
2006 
2007 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2008 	if (!resp) {
2009 		kfree(req);
2010 		return -ENOMEM;
2011 	}
2012 
2013 	priv->stats.rejuvenate_ack_req++;
2014 
2015 	ret = qmi_txn_init(&priv->qmi, &txn,
2016 			   wlfw_rejuvenate_ack_resp_msg_v01_ei, resp);
2017 	if (ret < 0) {
2018 		icnss_qmi_fatal_err(
2019 			"Fail to init txn for Rejuvenate Ack resp %d\n",
2020 			 ret);
2021 		goto out;
2022 	}
2023 
2024 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
2025 			       QMI_WLFW_REJUVENATE_ACK_REQ_V01,
2026 			       WLFW_REJUVENATE_ACK_REQ_MSG_V01_MAX_MSG_LEN,
2027 			       wlfw_rejuvenate_ack_req_msg_v01_ei, req);
2028 	if (ret < 0) {
2029 		qmi_txn_cancel(&txn);
2030 		icnss_qmi_fatal_err("Fail to send Rejuvenate Ack req %d\n",
2031 				    ret);
2032 		goto out;
2033 	}
2034 
2035 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
2036 	if (ret < 0) {
2037 		icnss_qmi_fatal_err(
2038 			     "Rejuvenate Ack resp wait failed with ret %d\n",
2039 			     ret);
2040 		goto out;
2041 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2042 		icnss_qmi_fatal_err(
2043 		   "QMI Rejuvenate Ack request rejected, result:%d error:%d\n",
2044 		    resp->resp.result, resp->resp.error);
2045 		ret = -resp->resp.result;
2046 		goto out;
2047 	}
2048 
2049 	priv->stats.rejuvenate_ack_resp++;
2050 
2051 	kfree(resp);
2052 	kfree(req);
2053 	return 0;
2054 
2055 out:
2056 	kfree(resp);
2057 	kfree(req);
2058 	priv->stats.rejuvenate_ack_err++;
2059 	return ret;
2060 }
2061 
2062 int wlfw_dynamic_feature_mask_send_sync_msg(struct icnss_priv *priv,
2063 					   uint64_t dynamic_feature_mask)
2064 {
2065 	int ret;
2066 	struct wlfw_dynamic_feature_mask_req_msg_v01 *req;
2067 	struct wlfw_dynamic_feature_mask_resp_msg_v01 *resp;
2068 	struct qmi_txn txn;
2069 
2070 	if (!priv)
2071 		return -ENODEV;
2072 
2073 	if (!test_bit(ICNSS_WLFW_CONNECTED, &priv->state)) {
2074 		icnss_pr_err("Invalid state for dynamic feature: 0x%lx\n",
2075 			     priv->state);
2076 		return -EINVAL;
2077 	}
2078 
2079 	if (!test_bit(FW_REJUVENATE_ENABLE, &priv->ctrl_params.quirks)) {
2080 		icnss_pr_dbg("FW rejuvenate is disabled from quirks\n");
2081 		return 0;
2082 	}
2083 
2084 	icnss_pr_dbg("Sending dynamic feature mask request, val 0x%llx, state: 0x%lx\n",
2085 		     dynamic_feature_mask, priv->state);
2086 
2087 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2088 	if (!req)
2089 		return -ENOMEM;
2090 
2091 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2092 	if (!resp) {
2093 		kfree(req);
2094 		return -ENOMEM;
2095 	}
2096 
2097 	req->mask_valid = 1;
2098 	req->mask = dynamic_feature_mask;
2099 
2100 	ret = qmi_txn_init(&priv->qmi, &txn,
2101 			   wlfw_dynamic_feature_mask_resp_msg_v01_ei, resp);
2102 	if (ret < 0) {
2103 		icnss_pr_err("Fail to init txn for Dynamic Feature Mask resp %d\n",
2104 			     ret);
2105 		goto out;
2106 	}
2107 
2108 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
2109 		       QMI_WLFW_DYNAMIC_FEATURE_MASK_REQ_V01,
2110 		       WLFW_DYNAMIC_FEATURE_MASK_REQ_MSG_V01_MAX_MSG_LEN,
2111 		       wlfw_dynamic_feature_mask_req_msg_v01_ei, req);
2112 	if (ret < 0) {
2113 		qmi_txn_cancel(&txn);
2114 		icnss_pr_err("Fail to send Dynamic Feature Mask req %d\n", ret);
2115 		goto out;
2116 	}
2117 
2118 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
2119 	if (ret < 0) {
2120 		icnss_pr_err("Dynamic Feature Mask resp wait failed with ret %d\n",
2121 			     ret);
2122 		goto out;
2123 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2124 		icnss_pr_err("QMI Dynamic Feature Mask request rejected, result:%d error:%d\n",
2125 			resp->resp.result, resp->resp.error);
2126 		ret = -resp->resp.result;
2127 		goto out;
2128 	}
2129 
2130 	icnss_pr_dbg("prev_mask_valid %u, prev_mask 0x%llx, curr_maks_valid %u, curr_mask 0x%llx\n",
2131 		     resp->prev_mask_valid, resp->prev_mask,
2132 		     resp->curr_mask_valid, resp->curr_mask);
2133 
2134 out:
2135 	kfree(resp);
2136 	kfree(req);
2137 	return ret;
2138 }
2139 
2140 void icnss_handle_rejuvenate(struct icnss_priv *priv)
2141 {
2142 	struct icnss_event_pd_service_down_data *event_data;
2143 	struct icnss_uevent_fw_down_data fw_down_data = {0};
2144 
2145 	event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
2146 	if (event_data == NULL)
2147 		return;
2148 
2149 	event_data->crashed = true;
2150 	event_data->fw_rejuvenate = true;
2151 	fw_down_data.crashed = true;
2152 	set_bit(ICNSS_REJUVENATE, &priv->state);
2153 
2154 	icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN,
2155 				 &fw_down_data);
2156 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
2157 				0, event_data);
2158 }
2159 
2160 int wlfw_qdss_trace_mem_info_send_sync(struct icnss_priv *priv)
2161 {
2162 	struct wlfw_qdss_trace_mem_info_req_msg_v01 *req;
2163 	struct wlfw_qdss_trace_mem_info_resp_msg_v01 *resp;
2164 	struct qmi_txn txn;
2165 	struct icnss_fw_mem *qdss_mem = priv->qdss_mem;
2166 	int ret = 0;
2167 	int i;
2168 
2169 	if (test_bit(ICNSS_FW_DOWN, &priv->state))
2170 		return -EINVAL;
2171 
2172 	icnss_pr_dbg("Sending QDSS trace mem info, state: 0x%lx\n",
2173 		     priv->state);
2174 
2175 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2176 	if (!req)
2177 		return -ENOMEM;
2178 
2179 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2180 	if (!resp) {
2181 		kfree(req);
2182 		return -ENOMEM;
2183 	}
2184 
2185 	req->mem_seg_len = priv->qdss_mem_seg_len;
2186 
2187 	if (priv->qdss_mem_seg_len >  QMI_WLFW_MAX_NUM_MEM_SEG_V01) {
2188 		icnss_pr_err("Invalid seg len %u\n",
2189 			     priv->qdss_mem_seg_len);
2190 		ret = -EINVAL;
2191 		goto out;
2192 	}
2193 
2194 	for (i = 0; i < req->mem_seg_len; i++) {
2195 		icnss_pr_dbg("Memory for FW, va: 0x%pK, pa: %pa, size: 0x%zx, type: %u\n",
2196 			     qdss_mem[i].va, &qdss_mem[i].pa,
2197 			     qdss_mem[i].size, qdss_mem[i].type);
2198 
2199 		req->mem_seg[i].addr = qdss_mem[i].pa;
2200 		req->mem_seg[i].size = qdss_mem[i].size;
2201 		req->mem_seg[i].type = qdss_mem[i].type;
2202 	}
2203 
2204 	ret = qmi_txn_init(&priv->qmi, &txn,
2205 			   wlfw_qdss_trace_mem_info_resp_msg_v01_ei, resp);
2206 	if (ret < 0) {
2207 		icnss_pr_err("Fail to initialize txn for QDSS trace mem request: err %d\n",
2208 			     ret);
2209 		goto out;
2210 	}
2211 
2212 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
2213 			       QMI_WLFW_QDSS_TRACE_MEM_INFO_REQ_V01,
2214 			       WLFW_QDSS_TRACE_MEM_INFO_REQ_MSG_V01_MAX_MSG_LEN,
2215 			       wlfw_qdss_trace_mem_info_req_msg_v01_ei, req);
2216 	if (ret < 0) {
2217 		qmi_txn_cancel(&txn);
2218 		icnss_pr_err("Fail to send QDSS trace mem info request: err %d\n",
2219 			     ret);
2220 		goto out;
2221 	}
2222 
2223 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
2224 	if (ret < 0) {
2225 		icnss_pr_err("Fail to wait for response of QDSS trace mem info request, err %d\n",
2226 			     ret);
2227 		goto out;
2228 	}
2229 
2230 	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2231 		icnss_pr_err("QDSS trace mem info request failed, result: %d, err: %d\n",
2232 			     resp->resp.result, resp->resp.error);
2233 		ret = -resp->resp.result;
2234 		goto out;
2235 	}
2236 
2237 	kfree(req);
2238 	kfree(resp);
2239 	return 0;
2240 
2241 out:
2242 	kfree(req);
2243 	kfree(resp);
2244 	return ret;
2245 }
2246 
2247 int icnss_wlfw_m3_dump_upload_done_send_sync(struct icnss_priv *priv,
2248 					     u32 pdev_id, int status)
2249 {
2250 	struct wlfw_m3_dump_upload_done_req_msg_v01 *req;
2251 	struct wlfw_m3_dump_upload_done_resp_msg_v01 *resp;
2252 	struct qmi_txn txn;
2253 	int ret = 0;
2254 
2255 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2256 	if (!req)
2257 		return -ENOMEM;
2258 
2259 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2260 	if (!resp) {
2261 		kfree(req);
2262 		return -ENOMEM;
2263 	}
2264 
2265 	icnss_pr_dbg("Sending M3 Upload done req, pdev %d, status %d\n",
2266 		     pdev_id, status);
2267 
2268 	req->pdev_id = pdev_id;
2269 	req->status = status;
2270 
2271 	ret = qmi_txn_init(&priv->qmi, &txn,
2272 			   wlfw_m3_dump_upload_done_resp_msg_v01_ei, resp);
2273 	if (ret < 0) {
2274 		icnss_pr_err("Fail to initialize txn for M3 dump upload done req: err %d\n",
2275 			     ret);
2276 		goto out;
2277 	}
2278 
2279 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
2280 			       QMI_WLFW_M3_DUMP_UPLOAD_DONE_REQ_V01,
2281 			       WLFW_M3_DUMP_UPLOAD_DONE_REQ_MSG_V01_MAX_MSG_LEN,
2282 			       wlfw_m3_dump_upload_done_req_msg_v01_ei, req);
2283 	if (ret < 0) {
2284 		qmi_txn_cancel(&txn);
2285 		icnss_pr_err("Fail to send M3 dump upload done request: err %d\n",
2286 			     ret);
2287 		goto out;
2288 	}
2289 
2290 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
2291 	if (ret < 0) {
2292 		icnss_pr_err("Fail to wait for response of M3 dump upload done request, err %d\n",
2293 			     ret);
2294 		goto out;
2295 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2296 		icnss_pr_err("M3 Dump Upload Done Req failed, result: %d, err: 0x%X\n",
2297 			     resp->resp.result, resp->resp.error);
2298 		ret = -resp->resp.result;
2299 		goto out;
2300 	}
2301 
2302 out:
2303 	kfree(req);
2304 	kfree(resp);
2305 	return ret;
2306 }
2307 
2308 static void fw_ready_ind_cb(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
2309 			    struct qmi_txn *txn, const void *data)
2310 {
2311 	struct icnss_priv *priv =
2312 		container_of(qmi, struct icnss_priv, qmi);
2313 
2314 	icnss_pr_dbg("Received FW Ready Indication\n");
2315 
2316 	if (!txn) {
2317 		pr_err("spurious indication\n");
2318 		return;
2319 	}
2320 
2321 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_FW_READY_IND,
2322 				0, NULL);
2323 }
2324 
2325 static void msa_ready_ind_cb(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
2326 			     struct qmi_txn *txn, const void *data)
2327 {
2328 	struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi);
2329 	struct device *dev = &priv->pdev->dev;
2330 	const struct wlfw_msa_ready_ind_msg_v01 *ind_msg = data;
2331 	uint64_t msa_base_addr = priv->msa_pa;
2332 	phys_addr_t hang_data_phy_addr;
2333 
2334 	icnss_pr_dbg("Received MSA Ready Indication\n");
2335 
2336 	if (!txn) {
2337 		pr_err("spurious indication\n");
2338 		return;
2339 	}
2340 
2341 	priv->stats.msa_ready_ind++;
2342 
2343 	/* Check if the length is valid &
2344 	 * the length should not be 0 and
2345 	 * should be <=  WLFW_MAX_HANG_EVENT_DATA_SIZE(400)
2346 	 */
2347 
2348 	if (ind_msg->hang_data_length_valid &&
2349 	    ind_msg->hang_data_length &&
2350 	    ind_msg->hang_data_length <= WLFW_MAX_HANG_EVENT_DATA_SIZE)
2351 		priv->hang_event_data_len = ind_msg->hang_data_length;
2352 	else
2353 		goto out;
2354 
2355 	/* Check if the offset is valid &
2356 	 * the offset should be in range of 0 to msa_mem_size-hang_data_length
2357 	 */
2358 
2359 	if (ind_msg->hang_data_addr_offset_valid &&
2360 	    (ind_msg->hang_data_addr_offset <= (priv->msa_mem_size -
2361 						 ind_msg->hang_data_length)))
2362 		hang_data_phy_addr = msa_base_addr +
2363 						ind_msg->hang_data_addr_offset;
2364 	else
2365 		goto out;
2366 
2367 	if (priv->hang_event_data_pa == hang_data_phy_addr)
2368 		goto exit;
2369 
2370 	priv->hang_event_data_pa = hang_data_phy_addr;
2371 	priv->hang_event_data_va = devm_ioremap(dev, priv->hang_event_data_pa,
2372 						ind_msg->hang_data_length);
2373 
2374 	if (!priv->hang_event_data_va) {
2375 		icnss_pr_err("Hang Data ioremap failed: phy addr: %pa\n",
2376 			     &priv->hang_event_data_pa);
2377 		goto fail;
2378 	}
2379 exit:
2380 	icnss_pr_dbg("Hang Event Data details,Offset:0x%x, Length:0x%x,va_addr: 0x%pK\n",
2381 		     ind_msg->hang_data_addr_offset,
2382 		     ind_msg->hang_data_length,
2383 		     priv->hang_event_data_va);
2384 
2385 	return;
2386 
2387 out:
2388 	icnss_pr_err("Invalid Hang Data details, Offset:0x%x, Length:0x%x",
2389 		     ind_msg->hang_data_addr_offset,
2390 		     ind_msg->hang_data_length);
2391 fail:
2392 	priv->hang_event_data_va = NULL;
2393 	priv->hang_event_data_pa = 0;
2394 	priv->hang_event_data_len = 0;
2395 }
2396 
2397 static void pin_connect_result_ind_cb(struct qmi_handle *qmi,
2398 				      struct sockaddr_qrtr *sq,
2399 				      struct qmi_txn *txn, const void *data)
2400 {
2401 	struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi);
2402 	const struct wlfw_pin_connect_result_ind_msg_v01 *ind_msg = data;
2403 
2404 	icnss_pr_dbg("Received Pin Connect Result Indication\n");
2405 
2406 	if (!txn) {
2407 		pr_err("spurious indication\n");
2408 		return;
2409 	}
2410 
2411 	if (ind_msg->pwr_pin_result_valid)
2412 		priv->pwr_pin_result = ind_msg->pwr_pin_result;
2413 	if (ind_msg->phy_io_pin_result_valid)
2414 		priv->phy_io_pin_result = ind_msg->phy_io_pin_result;
2415 	if (ind_msg->rf_pin_result_valid)
2416 		priv->rf_pin_result = ind_msg->rf_pin_result;
2417 
2418 	icnss_pr_dbg("Pin connect Result: pwr_pin: 0x%x phy_io_pin: 0x%x rf_io_pin: 0x%x\n",
2419 		     ind_msg->pwr_pin_result, ind_msg->phy_io_pin_result,
2420 		     ind_msg->rf_pin_result);
2421 	priv->stats.pin_connect_result++;
2422 }
2423 
2424 static void rejuvenate_ind_cb(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
2425 			      struct qmi_txn *txn, const void *data)
2426 {
2427 	struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi);
2428 	const struct wlfw_rejuvenate_ind_msg_v01 *ind_msg = data;
2429 
2430 	icnss_pr_dbg("Received Rejuvenate Indication\n");
2431 
2432 	if (!txn) {
2433 		pr_err("spurious indication\n");
2434 		return;
2435 	}
2436 
2437 	icnss_ignore_fw_timeout(true);
2438 
2439 	if (ind_msg->cause_for_rejuvenation_valid)
2440 		priv->cause_for_rejuvenation = ind_msg->cause_for_rejuvenation;
2441 	else
2442 		priv->cause_for_rejuvenation = 0;
2443 	if (ind_msg->requesting_sub_system_valid)
2444 		priv->requesting_sub_system = ind_msg->requesting_sub_system;
2445 	else
2446 		priv->requesting_sub_system = 0;
2447 	if (ind_msg->line_number_valid)
2448 		priv->line_number = ind_msg->line_number;
2449 	else
2450 		priv->line_number = 0;
2451 	if (ind_msg->function_name_valid)
2452 		memcpy(priv->function_name, ind_msg->function_name,
2453 		       QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1);
2454 	else
2455 		memset(priv->function_name, 0,
2456 		       QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1);
2457 
2458 	icnss_pr_info("Cause for rejuvenation: 0x%x, requesting sub-system: 0x%x, line number: %u, function name: %s\n",
2459 		      priv->cause_for_rejuvenation,
2460 		      priv->requesting_sub_system,
2461 		      priv->line_number,
2462 		      priv->function_name);
2463 
2464 	priv->stats.rejuvenate_ind++;
2465 
2466 	icnss_handle_rejuvenate(priv);
2467 }
2468 
2469 static void cal_done_ind_cb(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
2470 			    struct qmi_txn *txn, const void *data)
2471 {
2472 	struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi);
2473 
2474 	icnss_pr_dbg("Received QMI WLFW calibration done indication\n");
2475 
2476 	if (!txn) {
2477 		icnss_pr_err("Spurious indication\n");
2478 		return;
2479 	}
2480 
2481 	priv->cal_done = true;
2482 	clear_bit(ICNSS_COLD_BOOT_CAL, &priv->state);
2483 }
2484 
2485 static void fw_init_done_ind_cb(struct qmi_handle *qmi,
2486 				struct sockaddr_qrtr *sq,
2487 				struct qmi_txn *txn, const void *data)
2488 {
2489 	struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi);
2490 	struct device *dev = &priv->pdev->dev;
2491 	const struct wlfw_fw_init_done_ind_msg_v01 *ind_msg = data;
2492 	uint64_t msa_base_addr = priv->msa_pa;
2493 	phys_addr_t hang_data_phy_addr;
2494 
2495 	icnss_pr_dbg("Received QMI WLFW FW initialization done indication\n");
2496 
2497 	if (!txn) {
2498 		icnss_pr_err("Spurious indication\n");
2499 		return;
2500 	}
2501 
2502 	/* Check if the length is valid &
2503 	 * the length should not be 0 and
2504 	 * should be <=  WLFW_MAX_HANG_EVENT_DATA_SIZE(400)
2505 	 */
2506 
2507 	if (ind_msg->hang_data_length_valid &&
2508 	ind_msg->hang_data_length &&
2509 	ind_msg->hang_data_length <= WLFW_MAX_HANG_EVENT_DATA_SIZE)
2510 		priv->hang_event_data_len = ind_msg->hang_data_length;
2511 	else
2512 		goto out;
2513 
2514 	/* Check if the offset is valid &
2515 	 * the offset should be in range of 0 to msa_mem_size-hang_data_length
2516 	 */
2517 
2518 	if (ind_msg->hang_data_addr_offset_valid &&
2519 	    (ind_msg->hang_data_addr_offset <= (priv->msa_mem_size -
2520 					ind_msg->hang_data_length)))
2521 		hang_data_phy_addr = msa_base_addr +
2522 					ind_msg->hang_data_addr_offset;
2523 	else
2524 		goto out;
2525 
2526 	if (priv->hang_event_data_pa == hang_data_phy_addr)
2527 		goto exit;
2528 
2529 	priv->hang_event_data_pa = hang_data_phy_addr;
2530 	priv->hang_event_data_va = devm_ioremap(dev, priv->hang_event_data_pa,
2531 					ind_msg->hang_data_length);
2532 
2533 	if (!priv->hang_event_data_va) {
2534 		icnss_pr_err("Hang Data ioremap failed: phy addr: %pa\n",
2535 		&priv->hang_event_data_pa);
2536 		goto fail;
2537 	}
2538 
2539 exit:
2540 	icnss_pr_dbg("Hang Event Data details,Offset:0x%x, Length:0x%x,va_addr: 0x%pK\n",
2541 		     ind_msg->hang_data_addr_offset,
2542 		     ind_msg->hang_data_length,
2543 		     priv->hang_event_data_va);
2544 
2545 	goto post;
2546 
2547 out:
2548 	icnss_pr_err("Invalid Hang Data details, Offset:0x%x, Length:0x%x",
2549 		     ind_msg->hang_data_addr_offset,
2550 		     ind_msg->hang_data_length);
2551 fail:
2552 	priv->hang_event_data_va = NULL;
2553 	priv->hang_event_data_pa = 0;
2554 	priv->hang_event_data_len = 0;
2555 post:
2556 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_FW_INIT_DONE_IND,
2557 				0, NULL);
2558 
2559 }
2560 
2561 static void wlfw_qdss_trace_req_mem_ind_cb(struct qmi_handle *qmi,
2562 					   struct sockaddr_qrtr *sq,
2563 					   struct qmi_txn *txn,
2564 					   const void *data)
2565 {
2566 	struct icnss_priv *priv =
2567 		container_of(qmi, struct icnss_priv, qmi);
2568 	const struct wlfw_qdss_trace_req_mem_ind_msg_v01 *ind_msg = data;
2569 	int i;
2570 
2571 	icnss_pr_dbg("Received QMI WLFW QDSS trace request mem indication\n");
2572 
2573 	if (!txn) {
2574 		icnss_pr_err("Spurious indication\n");
2575 		return;
2576 	}
2577 
2578 	if (priv->qdss_mem_seg_len) {
2579 		icnss_pr_err("Ignore double allocation for QDSS trace, current len %u\n",
2580 			     priv->qdss_mem_seg_len);
2581 		return;
2582 	}
2583 
2584 	priv->qdss_mem_seg_len = ind_msg->mem_seg_len;
2585 
2586 	if (priv->qdss_mem_seg_len > QMI_WLFW_MAX_NUM_MEM_SEG_V01) {
2587 		icnss_pr_err("Invalid seg len %u\n",
2588 			     priv->qdss_mem_seg_len);
2589 		return;
2590 	}
2591 
2592 	for (i = 0; i < priv->qdss_mem_seg_len; i++) {
2593 		icnss_pr_dbg("QDSS requests for memory, size: 0x%x, type: %u\n",
2594 			     ind_msg->mem_seg[i].size,
2595 			     ind_msg->mem_seg[i].type);
2596 		priv->qdss_mem[i].type = ind_msg->mem_seg[i].type;
2597 		priv->qdss_mem[i].size = ind_msg->mem_seg[i].size;
2598 	}
2599 
2600 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM,
2601 				0, NULL);
2602 }
2603 
2604 static void wlfw_qdss_trace_save_ind_cb(struct qmi_handle *qmi,
2605 					struct sockaddr_qrtr *sq,
2606 					struct qmi_txn *txn,
2607 					const void *data)
2608 {
2609 	struct icnss_priv *priv =
2610 		container_of(qmi, struct icnss_priv, qmi);
2611 	const struct wlfw_qdss_trace_save_ind_msg_v01 *ind_msg = data;
2612 	struct icnss_qmi_event_qdss_trace_save_data *event_data;
2613 	int i = 0;
2614 
2615 	icnss_pr_dbg("Received QMI WLFW QDSS trace save indication\n");
2616 
2617 	if (!txn) {
2618 		icnss_pr_err("Spurious indication\n");
2619 		return;
2620 	}
2621 
2622 	icnss_pr_dbg("QDSS_trace_save info: source %u, total_size %u, file_name_valid %u, file_name %s\n",
2623 		     ind_msg->source, ind_msg->total_size,
2624 		     ind_msg->file_name_valid, ind_msg->file_name);
2625 
2626 	event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
2627 	if (!event_data)
2628 		return;
2629 
2630 	if (ind_msg->mem_seg_valid) {
2631 		if (ind_msg->mem_seg_len > QDSS_TRACE_SEG_LEN_MAX) {
2632 			icnss_pr_err("Invalid seg len %u\n",
2633 				     ind_msg->mem_seg_len);
2634 			goto free_event_data;
2635 		}
2636 		icnss_pr_dbg("QDSS_trace_save seg len %u\n",
2637 			     ind_msg->mem_seg_len);
2638 		event_data->mem_seg_len = ind_msg->mem_seg_len;
2639 		for (i = 0; i < ind_msg->mem_seg_len; i++) {
2640 			event_data->mem_seg[i].addr = ind_msg->mem_seg[i].addr;
2641 			event_data->mem_seg[i].size = ind_msg->mem_seg[i].size;
2642 			icnss_pr_dbg("seg-%d: addr 0x%llx size 0x%x\n",
2643 				     i, ind_msg->mem_seg[i].addr,
2644 				     ind_msg->mem_seg[i].size);
2645 		}
2646 	}
2647 
2648 	event_data->total_size = ind_msg->total_size;
2649 
2650 	if (ind_msg->file_name_valid)
2651 		strlcpy(event_data->file_name, ind_msg->file_name,
2652 			QDSS_TRACE_FILE_NAME_MAX + 1);
2653 
2654 	if (ind_msg->source == 1) {
2655 		if (!ind_msg->file_name_valid)
2656 			strlcpy(event_data->file_name, "qdss_trace_wcss_etb",
2657 				QDSS_TRACE_FILE_NAME_MAX + 1);
2658 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_QDSS_TRACE_REQ_DATA,
2659 				0, event_data);
2660 	} else {
2661 		if (!ind_msg->file_name_valid)
2662 			strlcpy(event_data->file_name, "qdss_trace_ddr",
2663 				QDSS_TRACE_FILE_NAME_MAX + 1);
2664 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_QDSS_TRACE_SAVE,
2665 				0, event_data);
2666 	}
2667 
2668 	return;
2669 
2670 free_event_data:
2671 	kfree(event_data);
2672 }
2673 
2674 static void wlfw_qdss_trace_free_ind_cb(struct qmi_handle *qmi,
2675 					struct sockaddr_qrtr *sq,
2676 					struct qmi_txn *txn,
2677 					const void *data)
2678 {
2679 	struct icnss_priv *priv =
2680 		container_of(qmi, struct icnss_priv, qmi);
2681 
2682 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_QDSS_TRACE_FREE,
2683 				0, NULL);
2684 }
2685 
2686 static void icnss_wlfw_respond_get_info_ind_cb(struct qmi_handle *qmi,
2687 					      struct sockaddr_qrtr *sq,
2688 					      struct qmi_txn *txn,
2689 					      const void *data)
2690 {
2691 	struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi);
2692 	const struct wlfw_respond_get_info_ind_msg_v01 *ind_msg = data;
2693 
2694 	if (!txn) {
2695 		icnss_pr_err("Spurious indication\n");
2696 		return;
2697 	}
2698 
2699 	icnss_pr_vdbg("Extract message with event length: %d, type: %d, is last: %d, seq no: %d\n",
2700 		     ind_msg->data_len, ind_msg->type,
2701 		     ind_msg->is_last, ind_msg->seq_no);
2702 
2703 	if (priv->get_info_cb_ctx && priv->get_info_cb)
2704 		priv->get_info_cb(priv->get_info_cb_ctx,
2705 				       (void *)ind_msg->data,
2706 				       ind_msg->data_len);
2707 }
2708 
2709 static void icnss_wlfw_m3_dump_upload_segs_req_ind_cb(struct qmi_handle *qmi,
2710 						      struct sockaddr_qrtr *sq,
2711 						      struct qmi_txn *txn,
2712 						      const void *d)
2713 {
2714 	struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi);
2715 	const struct wlfw_m3_dump_upload_segments_req_ind_msg_v01 *ind_msg = d;
2716 	struct icnss_m3_upload_segments_req_data *event_data = NULL;
2717 	u64 max_mapped_addr = 0;
2718 	u64 segment_addr = 0;
2719 	int i = 0;
2720 
2721 	icnss_pr_dbg("Received QMI WLFW M3 dump upload sigments indication\n");
2722 
2723 	if (!txn) {
2724 		icnss_pr_err("Spurious indication\n");
2725 		return;
2726 	}
2727 
2728 	icnss_pr_dbg("M3 Dump upload info: pdev_id: %d no_of_segments: %d\n",
2729 		     ind_msg->pdev_id, ind_msg->no_of_valid_segments);
2730 
2731 	if (ind_msg->no_of_valid_segments > QMI_WLFW_MAX_M3_SEGMENTS_SIZE_V01)
2732 		return;
2733 
2734 	event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
2735 	if (!event_data)
2736 		return;
2737 
2738 	event_data->pdev_id = ind_msg->pdev_id;
2739 	event_data->no_of_valid_segments = ind_msg->no_of_valid_segments;
2740 	max_mapped_addr = priv->msa_pa + priv->msa_mem_size;
2741 
2742 	for (i = 0; i < ind_msg->no_of_valid_segments; i++) {
2743 		segment_addr = ind_msg->m3_segment[i].addr &
2744 				M3_SEGMENT_ADDR_MASK;
2745 
2746 		if (ind_msg->m3_segment[i].size > priv->msa_mem_size ||
2747 		    segment_addr >= max_mapped_addr ||
2748 		    segment_addr < priv->msa_pa ||
2749 		    ind_msg->m3_segment[i].size +
2750 		    segment_addr > max_mapped_addr) {
2751 			icnss_pr_dbg("Received out of range Segment %d Addr: 0x%llx Size: 0x%x, Name: %s, type: %d\n",
2752 				     (i + 1), segment_addr,
2753 				     ind_msg->m3_segment[i].size,
2754 				     ind_msg->m3_segment[i].name,
2755 				     ind_msg->m3_segment[i].type);
2756 			goto out;
2757 		}
2758 
2759 		event_data->m3_segment[i].addr = segment_addr;
2760 		event_data->m3_segment[i].size = ind_msg->m3_segment[i].size;
2761 		event_data->m3_segment[i].type = ind_msg->m3_segment[i].type;
2762 		strlcpy(event_data->m3_segment[i].name,
2763 			ind_msg->m3_segment[i].name,
2764 			WLFW_MAX_STR_LEN + 1);
2765 
2766 		icnss_pr_dbg("Received Segment %d Addr: 0x%llx Size: 0x%x, Name: %s, type: %d\n",
2767 			     (i + 1), segment_addr,
2768 			     ind_msg->m3_segment[i].size,
2769 			     ind_msg->m3_segment[i].name,
2770 			     ind_msg->m3_segment[i].type);
2771 	}
2772 
2773 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_M3_DUMP_UPLOAD_REQ,
2774 				0, event_data);
2775 
2776 	return;
2777 out:
2778 	kfree(event_data);
2779 }
2780 
2781 static int icnss_wlfw_wfc_call_status_send_sync
2782 	(struct icnss_priv *priv,
2783 	 const struct ims_private_service_wfc_call_status_ind_msg_v01 *ind_msg)
2784 {
2785 	struct wlfw_wfc_call_status_req_msg_v01 *req;
2786 	struct wlfw_wfc_call_status_resp_msg_v01 *resp;
2787 	struct qmi_txn txn;
2788 	int ret = 0;
2789 
2790 	if (!test_bit(ICNSS_FW_READY, &priv->state)) {
2791 		icnss_pr_err("Drop IMS WFC indication as FW not initialized\n");
2792 		return -EINVAL;
2793 	}
2794 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2795 	if (!req)
2796 		return -ENOMEM;
2797 
2798 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2799 	if (!resp) {
2800 		kfree(req);
2801 		return -ENOMEM;
2802 	}
2803 
2804 	/**
2805 	 * WFC Call r1 design has CNSS as pass thru using opaque hex buffer.
2806 	 * But in r2 update QMI structure is expanded and as an effect qmi
2807 	 * decoded structures have padding. Thus we cannot use buffer design.
2808 	 * For backward compatibility for r1 design copy only wfc_call_active
2809 	 * value in hex buffer.
2810 	 */
2811 	req->wfc_call_status_len = sizeof(ind_msg->wfc_call_active);
2812 	req->wfc_call_status[0] = ind_msg->wfc_call_active;
2813 
2814 	/* wfc_call_active is mandatory in IMS indication */
2815 	req->wfc_call_active_valid = 1;
2816 	req->wfc_call_active = ind_msg->wfc_call_active;
2817 	req->all_wfc_calls_held_valid = ind_msg->all_wfc_calls_held_valid;
2818 	req->all_wfc_calls_held = ind_msg->all_wfc_calls_held;
2819 	req->is_wfc_emergency_valid = ind_msg->is_wfc_emergency_valid;
2820 	req->is_wfc_emergency = ind_msg->is_wfc_emergency;
2821 	req->twt_ims_start_valid = ind_msg->twt_ims_start_valid;
2822 	req->twt_ims_start = ind_msg->twt_ims_start;
2823 	req->twt_ims_int_valid = ind_msg->twt_ims_int_valid;
2824 	req->twt_ims_int = ind_msg->twt_ims_int;
2825 	req->media_quality_valid = ind_msg->media_quality_valid;
2826 	req->media_quality =
2827 		(enum wlfw_wfc_media_quality_v01)ind_msg->media_quality;
2828 
2829 	icnss_pr_dbg("CNSS->FW: WFC_CALL_REQ: state: 0x%lx\n",
2830 		     priv->state);
2831 
2832 	ret = qmi_txn_init(&priv->qmi, &txn,
2833 			   wlfw_wfc_call_status_resp_msg_v01_ei, resp);
2834 	if (ret < 0) {
2835 		icnss_pr_err("CNSS->FW: WFC_CALL_REQ: QMI Txn Init: Err %d\n",
2836 			     ret);
2837 		goto out;
2838 	}
2839 
2840 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
2841 			       QMI_WLFW_WFC_CALL_STATUS_REQ_V01,
2842 			       WLFW_WFC_CALL_STATUS_REQ_MSG_V01_MAX_MSG_LEN,
2843 			       wlfw_wfc_call_status_req_msg_v01_ei, req);
2844 	if (ret < 0) {
2845 		qmi_txn_cancel(&txn);
2846 		icnss_pr_err("CNSS->FW: WFC_CALL_REQ: QMI Send Err: %d\n",
2847 			     ret);
2848 		goto out;
2849 	}
2850 
2851 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
2852 	if (ret < 0) {
2853 		icnss_pr_err("FW->CNSS: WFC_CALL_RSP: QMI Wait Err: %d\n",
2854 			     ret);
2855 		goto out;
2856 	}
2857 
2858 	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2859 		icnss_pr_err("FW->CNSS: WFC_CALL_RSP: Result: %d Err: %d\n",
2860 			     resp->resp.result, resp->resp.error);
2861 		ret = -resp->resp.result;
2862 		goto out;
2863 	}
2864 	ret = 0;
2865 out:
2866 	kfree(req);
2867 	kfree(resp);
2868 	return ret;
2869 }
2870 
2871 static int icnss_ims_wfc_call_twt_cfg_send_sync
2872 	(struct icnss_priv *priv,
2873 	const struct wlfw_wfc_call_twt_config_ind_msg_v01 *ind_msg)
2874 {
2875 	struct ims_private_service_wfc_call_twt_config_req_msg_v01 *req;
2876 	struct ims_private_service_wfc_call_twt_config_rsp_msg_v01 *resp;
2877 	struct qmi_txn txn;
2878 	int ret = 0;
2879 
2880 	if (!test_bit(ICNSS_IMS_CONNECTED, &priv->state)) {
2881 		icnss_pr_err("Drop FW WFC indication as IMS QMI not connected\n");
2882 		return -EINVAL;
2883 	}
2884 
2885 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2886 	if (!req)
2887 		return -ENOMEM;
2888 
2889 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2890 	if (!resp) {
2891 		kfree(req);
2892 		return -ENOMEM;
2893 	}
2894 
2895 	req->twt_sta_start_valid = ind_msg->twt_sta_start_valid;
2896 	req->twt_sta_start = ind_msg->twt_sta_start;
2897 	req->twt_sta_int_valid = ind_msg->twt_sta_int_valid;
2898 	req->twt_sta_int = ind_msg->twt_sta_int;
2899 	req->twt_sta_upo_valid = ind_msg->twt_sta_upo_valid;
2900 	req->twt_sta_upo = ind_msg->twt_sta_upo;
2901 	req->twt_sta_sp_valid = ind_msg->twt_sta_sp_valid;
2902 	req->twt_sta_sp = ind_msg->twt_sta_sp;
2903 	req->twt_sta_dl_valid = req->twt_sta_dl_valid;
2904 	req->twt_sta_dl = req->twt_sta_dl;
2905 	req->twt_sta_config_changed_valid =
2906 				ind_msg->twt_sta_config_changed_valid;
2907 	req->twt_sta_config_changed = ind_msg->twt_sta_config_changed;
2908 
2909 	icnss_pr_dbg("CNSS->IMS: TWT_CFG_REQ: state: 0x%lx\n",
2910 		     priv->state);
2911 
2912 	ret =
2913 	qmi_txn_init(&priv->ims_qmi, &txn,
2914 		     ims_private_service_wfc_call_twt_config_rsp_msg_v01_ei,
2915 		     resp);
2916 	if (ret < 0) {
2917 		icnss_pr_err("CNSS->IMS: TWT_CFG_REQ: QMI Txn Init Err: %d\n",
2918 			    ret);
2919 		goto out;
2920 	}
2921 
2922 	ret =
2923 	qmi_send_request(&priv->ims_qmi, NULL, &txn,
2924 			 QMI_IMS_PRIVATE_SERVICE_WFC_CALL_TWT_CONFIG_REQ_V01,
2925 		IMS_PRIVATE_SERVICE_WFC_CALL_TWT_CONFIG_REQ_MSG_V01_MAX_MSG_LEN,
2926 		ims_private_service_wfc_call_twt_config_req_msg_v01_ei, req);
2927 	if (ret < 0) {
2928 		qmi_txn_cancel(&txn);
2929 		icnss_pr_err("CNSS->IMS: TWT_CFG_REQ: QMI Send Err: %d\n", ret);
2930 		goto out;
2931 	}
2932 
2933 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
2934 	if (ret < 0) {
2935 		icnss_pr_err("IMS->CNSS: TWT_CFG_RSP: QMI Wait Err: %d\n", ret);
2936 		goto out;
2937 	}
2938 
2939 	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2940 		icnss_pr_err("IMS->CNSS: TWT_CFG_RSP: Result: %d Err: %d\n",
2941 			    resp->resp.result, resp->resp.error);
2942 		ret = -resp->resp.result;
2943 		goto out;
2944 	}
2945 	ret = 0;
2946 out:
2947 	kfree(req);
2948 	kfree(resp);
2949 	return ret;
2950 }
2951 
2952 int icnss_process_twt_cfg_ind_event(struct icnss_priv *priv,
2953 				    void *data)
2954 {
2955 	int ret;
2956 	struct wlfw_wfc_call_twt_config_ind_msg_v01 *ind_msg = data;
2957 
2958 	ret = icnss_ims_wfc_call_twt_cfg_send_sync(priv, ind_msg);
2959 	kfree(data);
2960 	return ret;
2961 }
2962 
2963 static void icnss_wlfw_process_twt_cfg_ind(struct qmi_handle *qmi,
2964 					   struct sockaddr_qrtr *sq,
2965 					   struct qmi_txn *txn,
2966 					   const void *data)
2967 {
2968 	struct icnss_priv *priv =
2969 		container_of(qmi, struct icnss_priv, qmi);
2970 	const struct wlfw_wfc_call_twt_config_ind_msg_v01 *ind_msg = data;
2971 	struct wlfw_wfc_call_twt_config_ind_msg_v01 *event_data;
2972 
2973 	if (!txn) {
2974 		icnss_pr_err("FW->CNSS: TWT_CFG_IND: Spurious indication\n");
2975 		return;
2976 	}
2977 
2978 	if (!ind_msg) {
2979 		icnss_pr_err("FW->CNSS: TWT_CFG_IND: Invalid indication\n");
2980 		return;
2981 	}
2982 	icnss_pr_dbg("FW->CNSS: TWT_CFG_IND: %x %llx, %x %x, %x %x, %x %x, %x %x, %x %x\n",
2983 		     ind_msg->twt_sta_start_valid, ind_msg->twt_sta_start,
2984 		     ind_msg->twt_sta_int_valid, ind_msg->twt_sta_int,
2985 		     ind_msg->twt_sta_upo_valid, ind_msg->twt_sta_upo,
2986 		     ind_msg->twt_sta_sp_valid, ind_msg->twt_sta_sp,
2987 		     ind_msg->twt_sta_dl_valid, ind_msg->twt_sta_dl,
2988 		     ind_msg->twt_sta_config_changed_valid,
2989 		     ind_msg->twt_sta_config_changed);
2990 
2991 	event_data = kmemdup(ind_msg, sizeof(*event_data), GFP_KERNEL);
2992 	if (!event_data)
2993 		return;
2994 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_WLFW_TWT_CFG_IND, 0,
2995 			       event_data);
2996 }
2997 
2998 static struct qmi_msg_handler wlfw_msg_handlers[] = {
2999 	{
3000 		.type = QMI_INDICATION,
3001 		.msg_id = QMI_WLFW_FW_READY_IND_V01,
3002 		.ei = wlfw_fw_ready_ind_msg_v01_ei,
3003 		.decoded_size = sizeof(struct wlfw_fw_ready_ind_msg_v01),
3004 		.fn = fw_ready_ind_cb
3005 	},
3006 	{
3007 		.type = QMI_INDICATION,
3008 		.msg_id = QMI_WLFW_MSA_READY_IND_V01,
3009 		.ei = wlfw_msa_ready_ind_msg_v01_ei,
3010 		.decoded_size = sizeof(struct wlfw_msa_ready_ind_msg_v01),
3011 		.fn = msa_ready_ind_cb
3012 	},
3013 	{
3014 		.type = QMI_INDICATION,
3015 		.msg_id = QMI_WLFW_PIN_CONNECT_RESULT_IND_V01,
3016 		.ei = wlfw_pin_connect_result_ind_msg_v01_ei,
3017 		.decoded_size =
3018 		sizeof(struct wlfw_pin_connect_result_ind_msg_v01),
3019 		.fn = pin_connect_result_ind_cb
3020 	},
3021 	{
3022 		.type = QMI_INDICATION,
3023 		.msg_id = QMI_WLFW_REJUVENATE_IND_V01,
3024 		.ei = wlfw_rejuvenate_ind_msg_v01_ei,
3025 		.decoded_size = sizeof(struct wlfw_rejuvenate_ind_msg_v01),
3026 		.fn = rejuvenate_ind_cb
3027 	},
3028 	{
3029 		.type = QMI_INDICATION,
3030 		.msg_id = QMI_WLFW_CAL_DONE_IND_V01,
3031 		.ei = wlfw_cal_done_ind_msg_v01_ei,
3032 		.decoded_size = sizeof(struct wlfw_cal_done_ind_msg_v01),
3033 		.fn = cal_done_ind_cb
3034 	},
3035 	{
3036 		.type = QMI_INDICATION,
3037 		.msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01,
3038 		.ei = wlfw_fw_init_done_ind_msg_v01_ei,
3039 		.decoded_size = sizeof(struct wlfw_fw_init_done_ind_msg_v01),
3040 		.fn = fw_init_done_ind_cb
3041 	},
3042 	{
3043 		.type = QMI_INDICATION,
3044 		.msg_id = QMI_WLFW_QDSS_TRACE_REQ_MEM_IND_V01,
3045 		.ei = wlfw_qdss_trace_req_mem_ind_msg_v01_ei,
3046 		.decoded_size =
3047 		sizeof(struct wlfw_qdss_trace_req_mem_ind_msg_v01),
3048 		.fn = wlfw_qdss_trace_req_mem_ind_cb
3049 	},
3050 	{
3051 		.type = QMI_INDICATION,
3052 		.msg_id = QMI_WLFW_QDSS_TRACE_SAVE_IND_V01,
3053 		.ei = wlfw_qdss_trace_save_ind_msg_v01_ei,
3054 		.decoded_size =
3055 		sizeof(struct wlfw_qdss_trace_save_ind_msg_v01),
3056 		.fn = wlfw_qdss_trace_save_ind_cb
3057 	},
3058 	{
3059 		.type = QMI_INDICATION,
3060 		.msg_id = QMI_WLFW_QDSS_TRACE_FREE_IND_V01,
3061 		.ei = wlfw_qdss_trace_free_ind_msg_v01_ei,
3062 		.decoded_size =
3063 		sizeof(struct wlfw_qdss_trace_free_ind_msg_v01),
3064 		.fn = wlfw_qdss_trace_free_ind_cb
3065 	},
3066 	{
3067 		.type = QMI_INDICATION,
3068 		.msg_id = QMI_WLFW_RESPOND_GET_INFO_IND_V01,
3069 		.ei = wlfw_respond_get_info_ind_msg_v01_ei,
3070 		.decoded_size =
3071 		sizeof(struct wlfw_respond_get_info_ind_msg_v01),
3072 		.fn = icnss_wlfw_respond_get_info_ind_cb
3073 	},
3074 	{
3075 		.type = QMI_INDICATION,
3076 		.msg_id = QMI_WLFW_M3_DUMP_UPLOAD_SEGMENTS_REQ_IND_V01,
3077 		.ei = wlfw_m3_dump_upload_segments_req_ind_msg_v01_ei,
3078 		.decoded_size =
3079 		sizeof(struct wlfw_m3_dump_upload_segments_req_ind_msg_v01),
3080 		.fn = icnss_wlfw_m3_dump_upload_segs_req_ind_cb
3081 	},
3082 	{
3083 		.type = QMI_INDICATION,
3084 		.msg_id = QMI_WLFW_WFC_CALL_TWT_CONFIG_IND_V01,
3085 		.ei = wlfw_wfc_call_twt_config_ind_msg_v01_ei,
3086 		.decoded_size =
3087 		sizeof(struct wlfw_wfc_call_twt_config_ind_msg_v01),
3088 		.fn = icnss_wlfw_process_twt_cfg_ind
3089 	},
3090 	{}
3091 };
3092 
3093 int icnss_connect_to_fw_server(struct icnss_priv *priv, void *data)
3094 {
3095 	struct icnss_event_server_arrive_data *event_data = data;
3096 	struct qmi_handle *qmi = &priv->qmi;
3097 	struct sockaddr_qrtr sq = { 0 };
3098 	int ret = 0;
3099 
3100 	if (!priv) {
3101 		ret = -ENODEV;
3102 		goto out;
3103 	}
3104 
3105 	sq.sq_family = AF_QIPCRTR;
3106 	sq.sq_node = event_data->node;
3107 	sq.sq_port = event_data->port;
3108 	ret = kernel_connect(qmi->sock, (struct sockaddr *)&sq, sizeof(sq), 0);
3109 	if (ret < 0) {
3110 		icnss_pr_err("Fail to connect to remote service port\n");
3111 		goto out;
3112 	}
3113 
3114 	icnss_pr_info("QMI Server Connected: state: 0x%lx\n", priv->state);
3115 
3116 	kfree(data);
3117 	return 0;
3118 
3119 out:
3120 	kfree(data);
3121 	ICNSS_ASSERT(0);
3122 	return ret;
3123 }
3124 
3125 int icnss_clear_server(struct icnss_priv *priv)
3126 {
3127 	int ret;
3128 
3129 	if (!priv)
3130 		return -ENODEV;
3131 
3132 	icnss_pr_info("QMI Service Disconnected: 0x%lx\n", priv->state);
3133 	clear_bit(ICNSS_WLFW_CONNECTED, &priv->state);
3134 
3135 	icnss_unregister_fw_service(priv);
3136 
3137 	clear_bit(ICNSS_DEL_SERVER, &priv->state);
3138 
3139 	ret =  icnss_register_fw_service(priv);
3140 	if (ret < 0) {
3141 		icnss_pr_err("WLFW server registration failed\n");
3142 		ICNSS_ASSERT(0);
3143 	}
3144 
3145 	return 0;
3146 }
3147 
3148 static int wlfw_new_server(struct qmi_handle *qmi,
3149 			   struct qmi_service *service)
3150 {
3151 	struct icnss_priv *priv =
3152 		container_of(qmi, struct icnss_priv, qmi);
3153 	struct icnss_event_server_arrive_data *event_data;
3154 
3155 	if (priv && test_bit(ICNSS_DEL_SERVER, &priv->state)) {
3156 		icnss_pr_info("WLFW server delete in progress, Ignore server arrive: 0x%lx\n",
3157 			      priv->state);
3158 		return 0;
3159 	}
3160 
3161 	icnss_pr_dbg("WLFW server arrive: node %u port %u\n",
3162 		     service->node, service->port);
3163 
3164 	event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
3165 	if (event_data == NULL)
3166 		return -ENOMEM;
3167 
3168 	event_data->node = service->node;
3169 	event_data->port = service->port;
3170 
3171 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_SERVER_ARRIVE,
3172 				0, event_data);
3173 
3174 	return 0;
3175 }
3176 
3177 static void wlfw_del_server(struct qmi_handle *qmi,
3178 			    struct qmi_service *service)
3179 {
3180 	struct icnss_priv *priv = container_of(qmi, struct icnss_priv, qmi);
3181 
3182 	if (priv && test_bit(ICNSS_DEL_SERVER, &priv->state)) {
3183 		icnss_pr_info("WLFW server delete / icnss remove in progress, Ignore server delete:  0x%lx\n",
3184 			      priv->state);
3185 		return;
3186 	}
3187 
3188 	icnss_pr_dbg("WLFW server delete\n");
3189 
3190 	if (priv) {
3191 		set_bit(ICNSS_DEL_SERVER, &priv->state);
3192 		set_bit(ICNSS_FW_DOWN, &priv->state);
3193 		icnss_ignore_fw_timeout(true);
3194 	}
3195 
3196 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_SERVER_EXIT,
3197 				0, NULL);
3198 }
3199 
3200 static struct qmi_ops wlfw_qmi_ops = {
3201 	.new_server = wlfw_new_server,
3202 	.del_server = wlfw_del_server,
3203 };
3204 
3205 int icnss_register_fw_service(struct icnss_priv *priv)
3206 {
3207 	int ret;
3208 
3209 	ret = qmi_handle_init(&priv->qmi,
3210 			      WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
3211 			      &wlfw_qmi_ops, wlfw_msg_handlers);
3212 	if (ret < 0)
3213 		return ret;
3214 
3215 	if (priv->device_id == WCN6750_DEVICE_ID ||
3216 	    priv->device_id == WCN6450_DEVICE_ID)
3217 		ret = qmi_add_lookup(&priv->qmi, WLFW_SERVICE_ID_V01,
3218 				     WLFW_SERVICE_VERS_V01,
3219 				     WLFW_SERVICE_WCN_INS_ID_V01);
3220 	else
3221 		ret = qmi_add_lookup(&priv->qmi, WLFW_SERVICE_ID_V01,
3222 				     WLFW_SERVICE_VERS_V01,
3223 				     WLFW_SERVICE_INS_ID_V01);
3224 	return ret;
3225 }
3226 
3227 void icnss_unregister_fw_service(struct icnss_priv *priv)
3228 {
3229 	set_bit(ICNSS_DEL_SERVER, &priv->state);
3230 	qmi_handle_release(&priv->qmi);
3231 }
3232 
3233 int icnss_send_wlan_enable_to_fw(struct icnss_priv *priv,
3234 			struct icnss_wlan_enable_cfg *config,
3235 			enum icnss_driver_mode mode,
3236 			const char *host_version)
3237 {
3238 	struct wlfw_wlan_cfg_req_msg_v01 req;
3239 	u32 i;
3240 	int ret;
3241 
3242 	icnss_pr_dbg("Mode: %d, config: %pK, host_version: %s\n",
3243 		     mode, config, host_version);
3244 
3245 	memset(&req, 0, sizeof(req));
3246 
3247 	if (mode == ICNSS_WALTEST || mode == ICNSS_CCPM)
3248 		goto skip;
3249 
3250 	if (!config || !host_version) {
3251 		icnss_pr_err("Invalid cfg pointer, config: %pK, host_version: %pK\n",
3252 			     config, host_version);
3253 		ret = -EINVAL;
3254 		goto out;
3255 	}
3256 
3257 	req.host_version_valid = 1;
3258 	strlcpy(req.host_version, host_version,
3259 		WLFW_MAX_STR_LEN + 1);
3260 
3261 	req.tgt_cfg_valid = 1;
3262 	if (config->num_ce_tgt_cfg > WLFW_MAX_NUM_CE)
3263 		req.tgt_cfg_len = WLFW_MAX_NUM_CE;
3264 	else
3265 		req.tgt_cfg_len = config->num_ce_tgt_cfg;
3266 	for (i = 0; i < req.tgt_cfg_len; i++) {
3267 		req.tgt_cfg[i].pipe_num = config->ce_tgt_cfg[i].pipe_num;
3268 		req.tgt_cfg[i].pipe_dir = config->ce_tgt_cfg[i].pipe_dir;
3269 		req.tgt_cfg[i].nentries = config->ce_tgt_cfg[i].nentries;
3270 		req.tgt_cfg[i].nbytes_max = config->ce_tgt_cfg[i].nbytes_max;
3271 		req.tgt_cfg[i].flags = config->ce_tgt_cfg[i].flags;
3272 	}
3273 
3274 	req.svc_cfg_valid = 1;
3275 	if (config->num_ce_svc_pipe_cfg > WLFW_MAX_NUM_SVC)
3276 		req.svc_cfg_len = WLFW_MAX_NUM_SVC;
3277 	else
3278 		req.svc_cfg_len = config->num_ce_svc_pipe_cfg;
3279 	for (i = 0; i < req.svc_cfg_len; i++) {
3280 		req.svc_cfg[i].service_id = config->ce_svc_cfg[i].service_id;
3281 		req.svc_cfg[i].pipe_dir = config->ce_svc_cfg[i].pipe_dir;
3282 		req.svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num;
3283 	}
3284 
3285 	if (priv->device_id == WCN6750_DEVICE_ID) {
3286 		req.shadow_reg_v2_valid = 1;
3287 		if (config->num_shadow_reg_v2_cfg >
3288 			QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01)
3289 			req.shadow_reg_v2_len =
3290 				QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01;
3291 		else
3292 			req.shadow_reg_v2_len = config->num_shadow_reg_v2_cfg;
3293 
3294 		memcpy(req.shadow_reg_v2, config->shadow_reg_v2_cfg,
3295 			 sizeof(struct wlfw_shadow_reg_v2_cfg_s_v01) *
3296 			 req.shadow_reg_v2_len);
3297 	} else if (priv->device_id == ADRASTEA_DEVICE_ID) {
3298 		req.shadow_reg_valid = 1;
3299 		if (config->num_shadow_reg_cfg >
3300 			QMI_WLFW_MAX_NUM_SHADOW_REG_V01)
3301 			req.shadow_reg_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01;
3302 		else
3303 			req.shadow_reg_len = config->num_shadow_reg_cfg;
3304 
3305 		memcpy(req.shadow_reg, config->shadow_reg_cfg,
3306 		       sizeof(struct wlfw_msi_cfg_s_v01) * req.shadow_reg_len);
3307 	} else if (priv->device_id == WCN6450_DEVICE_ID) {
3308 		req.shadow_reg_v3_valid = 1;
3309 		if (config->num_shadow_reg_v3_cfg >
3310 			MAX_NUM_SHADOW_REG_V3)
3311 			req.shadow_reg_v3_len = MAX_NUM_SHADOW_REG_V3;
3312 		else
3313 			req.shadow_reg_v3_len = config->num_shadow_reg_v3_cfg;
3314 
3315 		memcpy(req.shadow_reg_v3, config->shadow_reg_v3_cfg,
3316 		       sizeof(struct wlfw_shadow_reg_v3_cfg_s_v01)
3317 		       * req.shadow_reg_v3_len);
3318 	}
3319 
3320 	ret = wlfw_wlan_cfg_send_sync_msg(priv, &req);
3321 	if (ret)
3322 		goto out;
3323 skip:
3324 	ret = wlfw_wlan_mode_send_sync_msg(priv,
3325 			   (enum wlfw_driver_mode_enum_v01)mode);
3326 out:
3327 	if (test_bit(SKIP_QMI, &priv->ctrl_params.quirks))
3328 		ret = 0;
3329 
3330 	return ret;
3331 }
3332 
3333 int icnss_send_wlan_disable_to_fw(struct icnss_priv *priv)
3334 {
3335 	enum wlfw_driver_mode_enum_v01 mode = QMI_WLFW_OFF_V01;
3336 
3337 	return wlfw_wlan_mode_send_sync_msg(priv, mode);
3338 }
3339 
3340 #ifdef CONFIG_ICNSS2_DEBUG
3341 static inline u32 icnss_get_host_build_type(void)
3342 {
3343 	return QMI_HOST_BUILD_TYPE_PRIMARY_V01;
3344 }
3345 #else
3346 static inline u32 icnss_get_host_build_type(void)
3347 {
3348 	return QMI_HOST_BUILD_TYPE_SECONDARY_V01;
3349 }
3350 #endif
3351 
3352 int wlfw_host_cap_send_sync(struct icnss_priv *priv)
3353 {
3354 	struct wlfw_host_cap_req_msg_v01 *req;
3355 	struct wlfw_host_cap_resp_msg_v01 *resp;
3356 	struct qmi_txn txn;
3357 	int ddr_type;
3358 	u32 gpio;
3359 	int ret = 0;
3360 	u64 iova_start = 0, iova_size = 0,
3361 	    iova_ipa_start = 0, iova_ipa_size = 0;
3362 
3363 	icnss_pr_dbg("Sending host capability message, state: 0x%lx\n",
3364 		    priv->state);
3365 
3366 	req = kzalloc(sizeof(*req), GFP_KERNEL);
3367 	if (!req)
3368 		return -ENOMEM;
3369 
3370 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
3371 	if (!resp) {
3372 		kfree(req);
3373 		return -ENOMEM;
3374 	}
3375 
3376 	req->num_clients_valid = 1;
3377 	req->num_clients = 1;
3378 
3379 	req->bdf_support_valid = 1;
3380 	req->bdf_support = 1;
3381 
3382 	req->cal_done_valid = 1;
3383 	req->cal_done = priv->cal_done;
3384 	icnss_pr_dbg("Calibration done is %d\n", priv->cal_done);
3385 
3386 	if (priv->smmu_s1_enable &&
3387 	    !icnss_get_iova(priv, &iova_start, &iova_size) &&
3388 	    !icnss_get_iova_ipa(priv, &iova_ipa_start,
3389 				&iova_ipa_size)) {
3390 		req->ddr_range_valid = 1;
3391 		req->ddr_range[0].start = iova_start;
3392 		req->ddr_range[0].size = iova_size + iova_ipa_size;
3393 		req->ddr_range[1].start = priv->msa_pa;
3394 		req->ddr_range[1].size = priv->msa_mem_size;
3395 		icnss_pr_dbg("Sending iova starting 0x%llx with size 0x%llx\n",
3396 			    req->ddr_range[0].start, req->ddr_range[0].size);
3397 		icnss_pr_dbg("Sending msa starting 0x%llx with size 0x%llx\n",
3398 			    req->ddr_range[1].start, req->ddr_range[1].size);
3399 	}
3400 
3401 	req->host_build_type_valid = 1;
3402 	req->host_build_type = icnss_get_host_build_type();
3403 
3404 	if (priv->wlan_en_delay_ms >= 100) {
3405 		icnss_pr_dbg("Setting WLAN_EN delay: %d ms\n",
3406 			     priv->wlan_en_delay_ms);
3407 		req->wlan_enable_delay_valid = 1;
3408 		req->wlan_enable_delay = priv->wlan_en_delay_ms;
3409 	}
3410 
3411 	/* ddr_type = 7(LPDDR4) and 8(LPDDR5) */
3412 	ddr_type = of_fdt_get_ddrtype();
3413 	if (ddr_type > 0) {
3414 		icnss_pr_dbg("DDR Type: %d\n", ddr_type);
3415 		req->ddr_type_valid = 1;
3416 		req->ddr_type = ddr_type;
3417 	}
3418 
3419 	ret = of_property_read_u32(priv->pdev->dev.of_node, "wlan-en-gpio",
3420 				   &gpio);
3421 	if (!ret) {
3422 		icnss_pr_dbg("WLAN_EN_GPIO modified through DT: %d\n", gpio);
3423 		req->gpio_info_valid = 1;
3424 		req->gpio_info[WLAN_EN_GPIO_V01] = gpio;
3425 	} else {
3426 		req->gpio_info[WLAN_EN_GPIO_V01] = 0xFFFF;
3427 	}
3428 
3429 	ret = of_property_read_u32(priv->pdev->dev.of_node, "bt-en-gpio",
3430 				   &gpio);
3431 	if (!ret) {
3432 		icnss_pr_dbg("BT_EN_GPIO modified through DT: %d\n", gpio);
3433 		req->gpio_info_valid = 1;
3434 		req->gpio_info[BT_EN_GPIO_V01] = gpio;
3435 	} else {
3436 		req->gpio_info[BT_EN_GPIO_V01] = 0xFFFF;
3437 	}
3438 
3439 	ret = of_property_read_u32(priv->pdev->dev.of_node, "host-sol-gpio",
3440 				   &gpio);
3441 	if (!ret) {
3442 		icnss_pr_dbg("HOST_SOL_GPIO modified through DT: %d\n", gpio);
3443 		req->gpio_info_valid = 1;
3444 		req->gpio_info[HOST_SOL_GPIO_V01] = gpio;
3445 	} else {
3446 		req->gpio_info[HOST_SOL_GPIO_V01] = 0xFFFF;
3447 	}
3448 
3449 	ret = of_property_read_u32(priv->pdev->dev.of_node, "target-sol-gpio",
3450 				   &gpio);
3451 	if (!ret) {
3452 		icnss_pr_dbg("TARGET_SOL_GPIO modified through DT: %d\n", gpio);
3453 		req->gpio_info_valid = 1;
3454 		req->gpio_info[TARGET_SOL_GPIO_V01] = gpio;
3455 	} else {
3456 		req->gpio_info[TARGET_SOL_GPIO_V01] = 0xFFFF;
3457 	}
3458 
3459 	req->gpio_info_len = GPIO_TYPE_MAX_V01;
3460 
3461 	ret = qmi_txn_init(&priv->qmi, &txn,
3462 			   wlfw_host_cap_resp_msg_v01_ei, resp);
3463 	if (ret < 0) {
3464 		icnss_pr_err("Failed to initialize txn for host capability request, err: %d\n",
3465 			    ret);
3466 		goto out;
3467 	}
3468 
3469 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
3470 			       QMI_WLFW_HOST_CAP_REQ_V01,
3471 			       WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN,
3472 			       wlfw_host_cap_req_msg_v01_ei, req);
3473 	if (ret < 0) {
3474 		qmi_txn_cancel(&txn);
3475 		icnss_pr_err("Failed to send host capability request, err: %d\n",
3476 			    ret);
3477 		goto out;
3478 	}
3479 
3480 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
3481 	if (ret < 0) {
3482 		icnss_pr_err("Failed to wait for response of host capability request, err: %d\n",
3483 			    ret);
3484 		goto out;
3485 	}
3486 
3487 	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
3488 		icnss_pr_err("Host capability request failed, result: %d, err: %d\n",
3489 			    resp->resp.result, resp->resp.error);
3490 		ret = -resp->resp.result;
3491 		goto out;
3492 	}
3493 
3494 	kfree(req);
3495 	kfree(resp);
3496 	return 0;
3497 
3498 out:
3499 	ICNSS_QMI_ASSERT();
3500 	kfree(req);
3501 	kfree(resp);
3502 	return ret;
3503 }
3504 
3505 int icnss_wlfw_get_info_send_sync(struct icnss_priv *plat_priv, int type,
3506 				 void *cmd, int cmd_len)
3507 {
3508 	struct wlfw_get_info_req_msg_v01 *req;
3509 	struct wlfw_get_info_resp_msg_v01 *resp;
3510 	struct qmi_txn txn;
3511 	int ret = 0;
3512 	int flags = GFP_KERNEL & ~__GFP_DIRECT_RECLAIM;
3513 
3514 	if (cmd_len > QMI_WLFW_MAX_DATA_SIZE_V01)
3515 		return -EINVAL;
3516 
3517 	if (test_bit(ICNSS_FW_DOWN, &plat_priv->state))
3518 		return -EINVAL;
3519 
3520 	req = kzalloc(sizeof(*req), flags);
3521 	if (!req)
3522 		return -ENOMEM;
3523 
3524 	resp = kzalloc(sizeof(*resp), flags);
3525 	if (!resp) {
3526 		kfree(req);
3527 		return -ENOMEM;
3528 	}
3529 
3530 	req->type = type;
3531 	req->data_len = cmd_len;
3532 	memcpy(req->data, cmd, req->data_len);
3533 
3534 	ret = qmi_txn_init(&plat_priv->qmi, &txn,
3535 			   wlfw_get_info_resp_msg_v01_ei, resp);
3536 	if (ret < 0) {
3537 		icnss_pr_err("Failed to initialize txn for get info request, err: %d\n",
3538 			    ret);
3539 		goto out;
3540 	}
3541 
3542 	ret = qmi_send_request(&plat_priv->qmi, NULL, &txn,
3543 			       QMI_WLFW_GET_INFO_REQ_V01,
3544 			       WLFW_GET_INFO_REQ_MSG_V01_MAX_MSG_LEN,
3545 			       wlfw_get_info_req_msg_v01_ei, req);
3546 	if (ret < 0) {
3547 		qmi_txn_cancel(&txn);
3548 		icnss_pr_err("Failed to send get info request, err: %d\n",
3549 			    ret);
3550 		goto out;
3551 	}
3552 
3553 	ret = qmi_txn_wait(&txn, plat_priv->ctrl_params.qmi_timeout);
3554 	if (ret < 0) {
3555 		icnss_pr_err("Failed to wait for response of get info request, err: %d\n",
3556 			    ret);
3557 		goto out;
3558 	}
3559 
3560 	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
3561 		icnss_pr_err("Get info request failed, result: %d, err: %d\n",
3562 			    resp->resp.result, resp->resp.error);
3563 		ret = -resp->resp.result;
3564 		goto out;
3565 	}
3566 
3567 	kfree(req);
3568 	kfree(resp);
3569 	return 0;
3570 
3571 out:
3572 	kfree(req);
3573 	kfree(resp);
3574 	return ret;
3575 }
3576 
3577 int wlfw_subsys_restart_level_msg(struct icnss_priv *penv, uint8_t restart_level)
3578 {
3579 	int ret;
3580 	struct wlfw_subsys_restart_level_req_msg_v01 *req;
3581 	struct wlfw_subsys_restart_level_resp_msg_v01 *resp;
3582 	struct qmi_txn txn;
3583 
3584 	if (!penv)
3585 		return -ENODEV;
3586 
3587 	if (test_bit(ICNSS_FW_DOWN, &penv->state))
3588 		return -EINVAL;
3589 
3590 	icnss_pr_dbg("Sending subsystem restart level: 0x%x\n", restart_level);
3591 
3592 	req = kzalloc(sizeof(*req), GFP_KERNEL);
3593 	if (!req)
3594 		return -ENOMEM;
3595 
3596 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
3597 	if (!resp) {
3598 		kfree(req);
3599 		return -ENOMEM;
3600 	}
3601 
3602 	req->restart_level_type_valid = 1;
3603 	req->restart_level_type = restart_level;
3604 
3605 	penv->stats.restart_level_req++;
3606 
3607 	ret = qmi_txn_init(&penv->qmi, &txn,
3608 			   wlfw_subsys_restart_level_resp_msg_v01_ei, resp);
3609 	if (ret < 0) {
3610 		icnss_pr_err("Fail to init txn for subsystem restart level, resp %d\n",
3611 			     ret);
3612 		goto out;
3613 	}
3614 
3615 	ret = qmi_send_request(&penv->qmi, NULL, &txn,
3616 			       QMI_WLFW_SUBSYS_RESTART_LEVEL_REQ_V01,
3617 			       WLFW_SUBSYS_RESTART_LEVEL_REQ_MSG_V01_MAX_MSG_LEN,
3618 			       wlfw_subsys_restart_level_req_msg_v01_ei, req);
3619 	if (ret < 0) {
3620 		qmi_txn_cancel(&txn);
3621 		icnss_pr_err("Fail to send subsystem restart level %d\n",
3622 			     ret);
3623 		goto out;
3624 	}
3625 
3626 	ret = qmi_txn_wait(&txn, penv->ctrl_params.qmi_timeout);
3627 	if (ret < 0) {
3628 		icnss_pr_err("Subsystem restart level timed out with ret %d\n",
3629 			     ret);
3630 		goto out;
3631 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
3632 		icnss_pr_err("Subsystem restart level request rejected,result:%d error:%d\n",
3633 			     resp->resp.result, resp->resp.error);
3634 		ret = -resp->resp.result;
3635 		goto out;
3636 	}
3637 
3638 	penv->stats.restart_level_resp++;
3639 
3640 	kfree(resp);
3641 	kfree(req);
3642 	return 0;
3643 
3644 out:
3645 	kfree(req);
3646 	kfree(resp);
3647 	penv->stats.restart_level_err++;
3648 	return ret;
3649 }
3650 
3651 int icnss_send_vbatt_update(struct icnss_priv *priv, uint64_t voltage_uv)
3652 {
3653 	int ret;
3654 	struct wlfw_vbatt_req_msg_v01 *req;
3655 	struct wlfw_vbatt_resp_msg_v01 *resp;
3656 	struct qmi_txn txn;
3657 
3658 	if (!priv)
3659 		return -ENODEV;
3660 
3661 	if (test_bit(ICNSS_FW_DOWN, &priv->state))
3662 		return -EINVAL;
3663 
3664 	icnss_pr_dbg("Sending Vbatt message, state: 0x%lx\n", priv->state);
3665 
3666 	req = kzalloc(sizeof(*req), GFP_KERNEL);
3667 	if (!req)
3668 		return -ENOMEM;
3669 
3670 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
3671 	if (!resp) {
3672 		kfree(req);
3673 		return -ENOMEM;
3674 	}
3675 
3676 	req->voltage_uv = voltage_uv;
3677 
3678 	ret = qmi_txn_init(&priv->qmi, &txn, wlfw_vbatt_resp_msg_v01_ei, resp);
3679 	if (ret < 0) {
3680 		icnss_pr_err("Fail to init txn for Vbatt message resp %d\n",
3681 			     ret);
3682 		goto out;
3683 	}
3684 
3685 	ret = qmi_send_request(&priv->qmi, NULL, &txn,
3686 			       QMI_WLFW_VBATT_REQ_V01,
3687 			       WLFW_VBATT_REQ_MSG_V01_MAX_MSG_LEN,
3688 			       wlfw_vbatt_req_msg_v01_ei, req);
3689 	if (ret < 0) {
3690 		qmi_txn_cancel(&txn);
3691 		icnss_pr_err("Fail to send Vbatt message req %d\n", ret);
3692 		goto out;
3693 	}
3694 
3695 	ret = qmi_txn_wait(&txn, priv->ctrl_params.qmi_timeout);
3696 	if (ret < 0) {
3697 		icnss_pr_err("VBATT message resp wait failed with ret %d\n",
3698 			     ret);
3699 		goto out;
3700 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
3701 		icnss_pr_err("QMI Vbatt message request rejected, result:%d error:%d\n",
3702 			     resp->resp.result, resp->resp.error);
3703 		ret = -resp->resp.result;
3704 		goto out;
3705 	}
3706 
3707 	kfree(resp);
3708 	kfree(req);
3709 	return 0;
3710 
3711 out:
3712 	kfree(resp);
3713 	kfree(req);
3714 	return ret;
3715 }
3716 
3717 int wlfw_wlan_hw_init_cfg_msg(struct icnss_priv *penv,
3718 			      enum wlfw_wlan_rf_subtype_v01 type)
3719 {
3720 	int ret;
3721 	struct wlfw_wlan_hw_init_cfg_req_msg_v01 *req;
3722 	struct wlfw_wlan_hw_init_cfg_resp_msg_v01 *resp;
3723 	struct qmi_txn txn;
3724 
3725 	if (!penv)
3726 		return -ENODEV;
3727 
3728 	icnss_pr_dbg("Sending hw init cfg, rf_subtype: 0x%x\n", type);
3729 
3730 	req = kzalloc(sizeof(*req), GFP_KERNEL);
3731 	if (!req)
3732 		return -ENOMEM;
3733 
3734 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
3735 	if (!resp) {
3736 		kfree(req);
3737 		return -ENOMEM;
3738 	}
3739 
3740 	req->rf_subtype_valid = 1;
3741 	req->rf_subtype = type;
3742 
3743 	ret = qmi_txn_init(&penv->qmi, &txn,
3744 			   wlfw_wlan_hw_init_cfg_resp_msg_v01_ei, resp);
3745 	if (ret < 0) {
3746 		icnss_pr_err("Fail to init txn for hw init cfg, resp %d\n",
3747 			     ret);
3748 		goto out;
3749 	}
3750 
3751 	ret = qmi_send_request(&penv->qmi, NULL, &txn,
3752 			       QMI_WLFW_WLAN_HW_INIT_CFG_REQ_V01,
3753 			       WLFW_WLAN_HW_INIT_CFG_REQ_MSG_V01_MAX_MSG_LEN,
3754 			       wlfw_wlan_hw_init_cfg_req_msg_v01_ei, req);
3755 	if (ret < 0) {
3756 		qmi_txn_cancel(&txn);
3757 		icnss_pr_err("Fail to send hw init cfg %d\n", ret);
3758 		goto out;
3759 	}
3760 
3761 	ret = qmi_txn_wait(&txn, penv->ctrl_params.qmi_timeout);
3762 	if (ret < 0) {
3763 		icnss_pr_err("HW init cfg timed out with ret %d\n",
3764 			     ret);
3765 		goto out;
3766 
3767 	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
3768 		icnss_pr_err("HW init cfg request rejected,result:%d error:%d\n",
3769 			     resp->resp.result, resp->resp.error);
3770 		ret = -resp->resp.result;
3771 		goto out;
3772 	}
3773 
3774 	kfree(resp);
3775 	kfree(req);
3776 	return 0;
3777 
3778 out:
3779 	kfree(req);
3780 	kfree(resp);
3781 	return ret;
3782 }
3783 
3784 /* IMS Service */
3785 int ims_subscribe_for_indication_send_async(struct icnss_priv *priv)
3786 {
3787 	int ret;
3788 	struct ims_private_service_subscribe_for_indications_req_msg_v01 *req;
3789 	struct qmi_txn *txn;
3790 
3791 	if (!priv)
3792 		return -ENODEV;
3793 
3794 	icnss_pr_dbg("Sending ASYNC ims subscribe for indication\n");
3795 
3796 	req = kzalloc(sizeof(*req), GFP_KERNEL);
3797 	if (!req)
3798 		return -ENOMEM;
3799 
3800 	req->wfc_call_status_valid = 1;
3801 	req->wfc_call_status = 1;
3802 
3803 	txn = &priv->ims_async_txn;
3804 	ret = qmi_txn_init(&priv->ims_qmi, txn, NULL, NULL);
3805 	if (ret < 0) {
3806 		icnss_pr_err("Fail to init txn for ims subscribe for indication resp %d\n",
3807 			     ret);
3808 		goto out;
3809 	}
3810 
3811 	ret = qmi_send_request
3812 	(&priv->ims_qmi, NULL, txn,
3813 	QMI_IMS_PRIVATE_SERVICE_SUBSCRIBE_FOR_INDICATIONS_REQ_V01,
3814 	IMS_PRIVATE_SERVICE_SUBSCRIBE_FOR_INDICATIONS_REQ_MSG_V01_MAX_MSG_LEN,
3815 	ims_private_service_subscribe_ind_req_msg_v01_ei, req);
3816 	if (ret < 0) {
3817 		qmi_txn_cancel(txn);
3818 		icnss_pr_err("Fail to send ims subscribe for indication req %d\n",
3819 			     ret);
3820 		goto out;
3821 	}
3822 
3823 	kfree(req);
3824 	return 0;
3825 
3826 out:
3827 	kfree(req);
3828 	return ret;
3829 }
3830 
3831 static void ims_subscribe_for_indication_resp_cb(struct qmi_handle *qmi,
3832 						 struct sockaddr_qrtr *sq,
3833 						 struct qmi_txn *txn,
3834 						 const void *data)
3835 {
3836 	const
3837 	struct ims_private_service_subscribe_for_indications_rsp_msg_v01 *resp =
3838 		data;
3839 
3840 	icnss_pr_dbg("Received IMS subscribe indication response\n");
3841 
3842 	if (!txn) {
3843 		icnss_pr_err("spurious response\n");
3844 		return;
3845 	}
3846 
3847 	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
3848 		icnss_pr_err("IMS subscribe for indication request rejected, result:%d error:%d\n",
3849 			     resp->resp.result, resp->resp.error);
3850 		txn->result = -resp->resp.result;
3851 	}
3852 }
3853 
3854 int icnss_process_wfc_call_ind_event(struct icnss_priv *priv,
3855 				     void *data)
3856 {
3857 	int ret;
3858 	struct ims_private_service_wfc_call_status_ind_msg_v01 *ind_msg = data;
3859 
3860 	ret = icnss_wlfw_wfc_call_status_send_sync(priv, ind_msg);
3861 	kfree(data);
3862 	return ret;
3863 }
3864 
3865 static void
3866 icnss_ims_process_wfc_call_ind_cb(struct qmi_handle *ims_qmi,
3867 				  struct sockaddr_qrtr *sq,
3868 				  struct qmi_txn *txn, const void *data)
3869 {
3870 	struct icnss_priv *priv =
3871 		container_of(ims_qmi, struct icnss_priv, ims_qmi);
3872 	const
3873 	struct ims_private_service_wfc_call_status_ind_msg_v01 *ind_msg = data;
3874 	struct ims_private_service_wfc_call_status_ind_msg_v01 *event_data;
3875 
3876 	if (!txn) {
3877 		icnss_pr_err("IMS->CNSS: WFC_CALL_IND: Spurious indication\n");
3878 		return;
3879 	}
3880 
3881 	if (!ind_msg) {
3882 		icnss_pr_err("IMS->CNSS: WFC_CALL_IND: Invalid indication\n");
3883 		return;
3884 	}
3885 	icnss_pr_dbg("IMS->CNSS: WFC_CALL_IND: %x, %x %x, %x %x, %x %llx, %x %x, %x %x\n",
3886 		     ind_msg->wfc_call_active, ind_msg->all_wfc_calls_held_valid,
3887 		     ind_msg->all_wfc_calls_held,
3888 		     ind_msg->is_wfc_emergency_valid, ind_msg->is_wfc_emergency,
3889 		     ind_msg->twt_ims_start_valid, ind_msg->twt_ims_start,
3890 		     ind_msg->twt_ims_int_valid, ind_msg->twt_ims_int,
3891 		     ind_msg->media_quality_valid, ind_msg->media_quality);
3892 
3893 	event_data = kmemdup(ind_msg, sizeof(*event_data), GFP_KERNEL);
3894 	if (!event_data)
3895 		return;
3896 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_IMS_WFC_CALL_IND,
3897 			       0, event_data);
3898 }
3899 
3900 static struct qmi_msg_handler qmi_ims_msg_handlers[] = {
3901 	{
3902 		.type = QMI_RESPONSE,
3903 		.msg_id =
3904 		QMI_IMS_PRIVATE_SERVICE_SUBSCRIBE_FOR_INDICATIONS_REQ_V01,
3905 		.ei =
3906 		ims_private_service_subscribe_ind_rsp_msg_v01_ei,
3907 		.decoded_size = sizeof(struct
3908 		ims_private_service_subscribe_for_indications_rsp_msg_v01),
3909 		.fn = ims_subscribe_for_indication_resp_cb
3910 	},
3911 	{
3912 		.type = QMI_INDICATION,
3913 		.msg_id = QMI_IMS_PRIVATE_SERVICE_WFC_CALL_STATUS_IND_V01,
3914 		.ei = ims_private_service_wfc_call_status_ind_msg_v01_ei,
3915 		.decoded_size =
3916 		sizeof(struct ims_private_service_wfc_call_status_ind_msg_v01),
3917 		.fn = icnss_ims_process_wfc_call_ind_cb
3918 	},
3919 	{}
3920 };
3921 
3922 static int ims_new_server(struct qmi_handle *qmi,
3923 			  struct qmi_service *service)
3924 {
3925 	struct icnss_priv *priv =
3926 		container_of(qmi, struct icnss_priv, ims_qmi);
3927 	struct sockaddr_qrtr sq = { 0 };
3928 	int ret = 0;
3929 
3930 	icnss_pr_dbg("IMS server arrive: node %u port %u\n",
3931 		    service->node, service->port);
3932 
3933 	sq.sq_family = AF_QIPCRTR;
3934 	sq.sq_node = service->node;
3935 	sq.sq_port = service->port;
3936 	ret = kernel_connect(qmi->sock, (struct sockaddr *)&sq, sizeof(sq), 0);
3937 	if (ret < 0) {
3938 		icnss_pr_err("Fail to connect to remote service port\n");
3939 		return ret;
3940 	}
3941 
3942 	set_bit(ICNSS_IMS_CONNECTED, &priv->state);
3943 	icnss_pr_dbg("IMS Server Connected: 0x%lx\n",
3944 		    priv->state);
3945 
3946 	ret = ims_subscribe_for_indication_send_async(priv);
3947 	return ret;
3948 }
3949 
3950 static void ims_del_server(struct qmi_handle *qmi,
3951 			   struct qmi_service *service)
3952 {
3953 	struct icnss_priv *priv =
3954 		container_of(qmi, struct icnss_priv, ims_qmi);
3955 
3956 	icnss_pr_dbg("IMS server exit\n");
3957 
3958 	clear_bit(ICNSS_IMS_CONNECTED, &priv->state);
3959 }
3960 
3961 static struct qmi_ops ims_qmi_ops = {
3962 	.new_server = ims_new_server,
3963 	.del_server = ims_del_server,
3964 };
3965 
3966 int icnss_register_ims_service(struct icnss_priv *priv)
3967 {
3968 	int ret;
3969 
3970 	ret = qmi_handle_init(&priv->ims_qmi,
3971 			      IMSPRIVATE_SERVICE_MAX_MSG_LEN,
3972 			      &ims_qmi_ops, qmi_ims_msg_handlers);
3973 	if (ret < 0)
3974 		return ret;
3975 
3976 	ret = qmi_add_lookup(&priv->ims_qmi, IMSPRIVATE_SERVICE_ID_V01,
3977 			     IMSPRIVATE_SERVICE_VERS_V01, 0);
3978 	return ret;
3979 }
3980 
3981 void icnss_unregister_ims_service(struct icnss_priv *priv)
3982 {
3983 	qmi_handle_release(&priv->ims_qmi);
3984 }
3985