]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/net/wireless/ath/ath10k/qmi.c
Merge tag 'sound-5.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
[linux.git] / drivers / net / wireless / ath / ath10k / qmi.c
1 // SPDX-License-Identifier: ISC
2 /*
3  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
4  */
5
6 #include <linux/completion.h>
7 #include <linux/device.h>
8 #include <linux/debugfs.h>
9 #include <linux/idr.h>
10 #include <linux/kernel.h>
11 #include <linux/of.h>
12 #include <linux/of_address.h>
13 #include <linux/module.h>
14 #include <linux/net.h>
15 #include <linux/platform_device.h>
16 #include <linux/qcom_scm.h>
17 #include <linux/string.h>
18 #include <net/sock.h>
19
20 #include "debug.h"
21 #include "snoc.h"
22
23 #define ATH10K_QMI_CLIENT_ID            0x4b4e454c
24 #define ATH10K_QMI_TIMEOUT              30
25
26 static int ath10k_qmi_map_msa_permission(struct ath10k_qmi *qmi,
27                                          struct ath10k_msa_mem_info *mem_info)
28 {
29         struct qcom_scm_vmperm dst_perms[3];
30         struct ath10k *ar = qmi->ar;
31         unsigned int src_perms;
32         u32 perm_count;
33         int ret;
34
35         src_perms = BIT(QCOM_SCM_VMID_HLOS);
36
37         dst_perms[0].vmid = QCOM_SCM_VMID_MSS_MSA;
38         dst_perms[0].perm = QCOM_SCM_PERM_RW;
39         dst_perms[1].vmid = QCOM_SCM_VMID_WLAN;
40         dst_perms[1].perm = QCOM_SCM_PERM_RW;
41
42         if (mem_info->secure) {
43                 perm_count = 2;
44         } else {
45                 dst_perms[2].vmid = QCOM_SCM_VMID_WLAN_CE;
46                 dst_perms[2].perm = QCOM_SCM_PERM_RW;
47                 perm_count = 3;
48         }
49
50         ret = qcom_scm_assign_mem(mem_info->addr, mem_info->size,
51                                   &src_perms, dst_perms, perm_count);
52         if (ret < 0)
53                 ath10k_err(ar, "failed to assign msa map permissions: %d\n", ret);
54
55         return ret;
56 }
57
58 static int ath10k_qmi_unmap_msa_permission(struct ath10k_qmi *qmi,
59                                            struct ath10k_msa_mem_info *mem_info)
60 {
61         struct qcom_scm_vmperm dst_perms;
62         struct ath10k *ar = qmi->ar;
63         unsigned int src_perms;
64         int ret;
65
66         src_perms = BIT(QCOM_SCM_VMID_MSS_MSA) | BIT(QCOM_SCM_VMID_WLAN);
67
68         if (!mem_info->secure)
69                 src_perms |= BIT(QCOM_SCM_VMID_WLAN_CE);
70
71         dst_perms.vmid = QCOM_SCM_VMID_HLOS;
72         dst_perms.perm = QCOM_SCM_PERM_RW;
73
74         ret = qcom_scm_assign_mem(mem_info->addr, mem_info->size,
75                                   &src_perms, &dst_perms, 1);
76         if (ret < 0)
77                 ath10k_err(ar, "failed to unmap msa permissions: %d\n", ret);
78
79         return ret;
80 }
81
82 static int ath10k_qmi_setup_msa_permissions(struct ath10k_qmi *qmi)
83 {
84         int ret;
85         int i;
86
87         for (i = 0; i < qmi->nr_mem_region; i++) {
88                 ret = ath10k_qmi_map_msa_permission(qmi, &qmi->mem_region[i]);
89                 if (ret)
90                         goto err_unmap;
91         }
92
93         return 0;
94
95 err_unmap:
96         for (i--; i >= 0; i--)
97                 ath10k_qmi_unmap_msa_permission(qmi, &qmi->mem_region[i]);
98         return ret;
99 }
100
101 static void ath10k_qmi_remove_msa_permission(struct ath10k_qmi *qmi)
102 {
103         int i;
104
105         for (i = 0; i < qmi->nr_mem_region; i++)
106                 ath10k_qmi_unmap_msa_permission(qmi, &qmi->mem_region[i]);
107 }
108
109 static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi)
110 {
111         struct wlfw_msa_info_resp_msg_v01 resp = {};
112         struct wlfw_msa_info_req_msg_v01 req = {};
113         struct ath10k *ar = qmi->ar;
114         struct qmi_txn txn;
115         int ret;
116         int i;
117
118         req.msa_addr = qmi->msa_pa;
119         req.size = qmi->msa_mem_size;
120
121         ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
122                            wlfw_msa_info_resp_msg_v01_ei, &resp);
123         if (ret < 0)
124                 goto out;
125
126         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
127                                QMI_WLFW_MSA_INFO_REQ_V01,
128                                WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN,
129                                wlfw_msa_info_req_msg_v01_ei, &req);
130         if (ret < 0) {
131                 qmi_txn_cancel(&txn);
132                 ath10k_err(ar, "failed to send msa mem info req: %d\n", ret);
133                 goto out;
134         }
135
136         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
137         if (ret < 0)
138                 goto out;
139
140         if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
141                 ath10k_err(ar, "msa info req rejected: %d\n", resp.resp.error);
142                 ret = -EINVAL;
143                 goto out;
144         }
145
146         if (resp.mem_region_info_len > QMI_WLFW_MAX_MEM_REG_V01) {
147                 ath10k_err(ar, "invalid memory region length received: %d\n",
148                            resp.mem_region_info_len);
149                 ret = -EINVAL;
150                 goto out;
151         }
152
153         qmi->nr_mem_region = resp.mem_region_info_len;
154         for (i = 0; i < resp.mem_region_info_len; i++) {
155                 qmi->mem_region[i].addr = resp.mem_region_info[i].region_addr;
156                 qmi->mem_region[i].size = resp.mem_region_info[i].size;
157                 qmi->mem_region[i].secure = resp.mem_region_info[i].secure_flag;
158                 ath10k_dbg(ar, ATH10K_DBG_QMI,
159                            "qmi msa mem region %d addr 0x%pa size 0x%x flag 0x%08x\n",
160                            i, &qmi->mem_region[i].addr,
161                            qmi->mem_region[i].size,
162                            qmi->mem_region[i].secure);
163         }
164
165         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa mem info request completed\n");
166         return 0;
167
168 out:
169         return ret;
170 }
171
172 static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi)
173 {
174         struct wlfw_msa_ready_resp_msg_v01 resp = {};
175         struct wlfw_msa_ready_req_msg_v01 req = {};
176         struct ath10k *ar = qmi->ar;
177         struct qmi_txn txn;
178         int ret;
179
180         ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
181                            wlfw_msa_ready_resp_msg_v01_ei, &resp);
182         if (ret < 0)
183                 goto out;
184
185         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
186                                QMI_WLFW_MSA_READY_REQ_V01,
187                                WLFW_MSA_READY_REQ_MSG_V01_MAX_MSG_LEN,
188                                wlfw_msa_ready_req_msg_v01_ei, &req);
189         if (ret < 0) {
190                 qmi_txn_cancel(&txn);
191                 ath10k_err(ar, "failed to send msa mem ready request: %d\n", ret);
192                 goto out;
193         }
194
195         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
196         if (ret < 0)
197                 goto out;
198
199         if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
200                 ath10k_err(ar, "msa ready request rejected: %d\n", resp.resp.error);
201                 ret = -EINVAL;
202         }
203
204         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa mem ready request completed\n");
205         return 0;
206
207 out:
208         return ret;
209 }
210
211 static int ath10k_qmi_bdf_dnld_send_sync(struct ath10k_qmi *qmi)
212 {
213         struct wlfw_bdf_download_resp_msg_v01 resp = {};
214         struct wlfw_bdf_download_req_msg_v01 *req;
215         struct ath10k *ar = qmi->ar;
216         unsigned int remaining;
217         struct qmi_txn txn;
218         const u8 *temp;
219         int ret;
220
221         req = kzalloc(sizeof(*req), GFP_KERNEL);
222         if (!req)
223                 return -ENOMEM;
224
225         temp = ar->normal_mode_fw.board_data;
226         remaining = ar->normal_mode_fw.board_len;
227
228         while (remaining) {
229                 req->valid = 1;
230                 req->file_id_valid = 1;
231                 req->file_id = 0;
232                 req->total_size_valid = 1;
233                 req->total_size = ar->normal_mode_fw.board_len;
234                 req->seg_id_valid = 1;
235                 req->data_valid = 1;
236                 req->end_valid = 1;
237
238                 if (remaining > QMI_WLFW_MAX_DATA_SIZE_V01) {
239                         req->data_len = QMI_WLFW_MAX_DATA_SIZE_V01;
240                 } else {
241                         req->data_len = remaining;
242                         req->end = 1;
243                 }
244
245                 memcpy(req->data, temp, req->data_len);
246
247                 ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
248                                    wlfw_bdf_download_resp_msg_v01_ei,
249                                    &resp);
250                 if (ret < 0)
251                         goto out;
252
253                 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
254                                        QMI_WLFW_BDF_DOWNLOAD_REQ_V01,
255                                        WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
256                                        wlfw_bdf_download_req_msg_v01_ei, req);
257                 if (ret < 0) {
258                         qmi_txn_cancel(&txn);
259                         goto out;
260                 }
261
262                 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
263
264                 if (ret < 0)
265                         goto out;
266
267                 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
268                         ath10k_err(ar, "failed to download board data file: %d\n",
269                                    resp.resp.error);
270                         ret = -EINVAL;
271                         goto out;
272                 }
273
274                 remaining -= req->data_len;
275                 temp += req->data_len;
276                 req->seg_id++;
277         }
278
279         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi bdf download request completed\n");
280
281         kfree(req);
282         return 0;
283
284 out:
285         kfree(req);
286         return ret;
287 }
288
289 static int ath10k_qmi_send_cal_report_req(struct ath10k_qmi *qmi)
290 {
291         struct wlfw_cal_report_resp_msg_v01 resp = {};
292         struct wlfw_cal_report_req_msg_v01 req = {};
293         struct ath10k *ar = qmi->ar;
294         struct qmi_txn txn;
295         int i, j = 0;
296         int ret;
297
298         ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cal_report_resp_msg_v01_ei,
299                            &resp);
300         if (ret < 0)
301                 goto out;
302
303         for (i = 0; i < QMI_WLFW_MAX_NUM_CAL_V01; i++) {
304                 if (qmi->cal_data[i].total_size &&
305                     qmi->cal_data[i].data) {
306                         req.meta_data[j] = qmi->cal_data[i].cal_id;
307                         j++;
308                 }
309         }
310         req.meta_data_len = j;
311
312         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
313                                QMI_WLFW_CAL_REPORT_REQ_V01,
314                                WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN,
315                                wlfw_cal_report_req_msg_v01_ei, &req);
316         if (ret < 0) {
317                 qmi_txn_cancel(&txn);
318                 ath10k_err(ar, "failed to send calibration request: %d\n", ret);
319                 goto out;
320         }
321
322         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
323         if (ret < 0)
324                 goto out;
325
326         if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
327                 ath10k_err(ar, "calibration request rejected: %d\n", resp.resp.error);
328                 ret = -EINVAL;
329                 goto out;
330         }
331
332         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi cal report request completed\n");
333         return 0;
334
335 out:
336         return ret;
337 }
338
339 static int
340 ath10k_qmi_mode_send_sync_msg(struct ath10k *ar, enum wlfw_driver_mode_enum_v01 mode)
341 {
342         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
343         struct ath10k_qmi *qmi = ar_snoc->qmi;
344         struct wlfw_wlan_mode_resp_msg_v01 resp = {};
345         struct wlfw_wlan_mode_req_msg_v01 req = {};
346         struct qmi_txn txn;
347         int ret;
348
349         ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
350                            wlfw_wlan_mode_resp_msg_v01_ei,
351                            &resp);
352         if (ret < 0)
353                 goto out;
354
355         req.mode = mode;
356         req.hw_debug_valid = 1;
357         req.hw_debug = 0;
358
359         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
360                                QMI_WLFW_WLAN_MODE_REQ_V01,
361                                WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN,
362                                wlfw_wlan_mode_req_msg_v01_ei, &req);
363         if (ret < 0) {
364                 qmi_txn_cancel(&txn);
365                 ath10k_err(ar, "failed to send wlan mode %d request: %d\n", mode, ret);
366                 goto out;
367         }
368
369         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
370         if (ret < 0)
371                 goto out;
372
373         if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
374                 ath10k_err(ar, "more request rejected: %d\n", resp.resp.error);
375                 ret = -EINVAL;
376                 goto out;
377         }
378
379         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wlan mode req completed: %d\n", mode);
380         return 0;
381
382 out:
383         return ret;
384 }
385
386 static int
387 ath10k_qmi_cfg_send_sync_msg(struct ath10k *ar,
388                              struct ath10k_qmi_wlan_enable_cfg *config,
389                              const char *version)
390 {
391         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
392         struct ath10k_qmi *qmi = ar_snoc->qmi;
393         struct wlfw_wlan_cfg_resp_msg_v01 resp = {};
394         struct wlfw_wlan_cfg_req_msg_v01 *req;
395         struct qmi_txn txn;
396         int ret;
397         u32 i;
398
399         req = kzalloc(sizeof(*req), GFP_KERNEL);
400         if (!req)
401                 return -ENOMEM;
402
403         ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
404                            wlfw_wlan_cfg_resp_msg_v01_ei,
405                            &resp);
406         if (ret < 0)
407                 goto out;
408
409         req->host_version_valid = 0;
410
411         req->tgt_cfg_valid = 1;
412         if (config->num_ce_tgt_cfg > QMI_WLFW_MAX_NUM_CE_V01)
413                 req->tgt_cfg_len = QMI_WLFW_MAX_NUM_CE_V01;
414         else
415                 req->tgt_cfg_len = config->num_ce_tgt_cfg;
416         for (i = 0; i < req->tgt_cfg_len; i++) {
417                 req->tgt_cfg[i].pipe_num = config->ce_tgt_cfg[i].pipe_num;
418                 req->tgt_cfg[i].pipe_dir = config->ce_tgt_cfg[i].pipe_dir;
419                 req->tgt_cfg[i].nentries = config->ce_tgt_cfg[i].nentries;
420                 req->tgt_cfg[i].nbytes_max = config->ce_tgt_cfg[i].nbytes_max;
421                 req->tgt_cfg[i].flags = config->ce_tgt_cfg[i].flags;
422         }
423
424         req->svc_cfg_valid = 1;
425         if (config->num_ce_svc_pipe_cfg > QMI_WLFW_MAX_NUM_SVC_V01)
426                 req->svc_cfg_len = QMI_WLFW_MAX_NUM_SVC_V01;
427         else
428                 req->svc_cfg_len = config->num_ce_svc_pipe_cfg;
429         for (i = 0; i < req->svc_cfg_len; i++) {
430                 req->svc_cfg[i].service_id = config->ce_svc_cfg[i].service_id;
431                 req->svc_cfg[i].pipe_dir = config->ce_svc_cfg[i].pipe_dir;
432                 req->svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num;
433         }
434
435         req->shadow_reg_valid = 1;
436         if (config->num_shadow_reg_cfg >
437             QMI_WLFW_MAX_NUM_SHADOW_REG_V01)
438                 req->shadow_reg_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01;
439         else
440                 req->shadow_reg_len = config->num_shadow_reg_cfg;
441
442         memcpy(req->shadow_reg, config->shadow_reg_cfg,
443                sizeof(struct wlfw_shadow_reg_cfg_s_v01) * req->shadow_reg_len);
444
445         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
446                                QMI_WLFW_WLAN_CFG_REQ_V01,
447                                WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN,
448                                wlfw_wlan_cfg_req_msg_v01_ei, req);
449         if (ret < 0) {
450                 qmi_txn_cancel(&txn);
451                 ath10k_err(ar, "failed to send config request: %d\n", ret);
452                 goto out;
453         }
454
455         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
456         if (ret < 0)
457                 goto out;
458
459         if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
460                 ath10k_err(ar, "config request rejected: %d\n", resp.resp.error);
461                 ret = -EINVAL;
462                 goto out;
463         }
464
465         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi config request completed\n");
466         kfree(req);
467         return 0;
468
469 out:
470         kfree(req);
471         return ret;
472 }
473
474 int ath10k_qmi_wlan_enable(struct ath10k *ar,
475                            struct ath10k_qmi_wlan_enable_cfg *config,
476                            enum wlfw_driver_mode_enum_v01 mode,
477                            const char *version)
478 {
479         int ret;
480
481         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi mode %d config %p\n",
482                    mode, config);
483
484         ret = ath10k_qmi_cfg_send_sync_msg(ar, config, version);
485         if (ret) {
486                 ath10k_err(ar, "failed to send qmi config: %d\n", ret);
487                 return ret;
488         }
489
490         ret = ath10k_qmi_mode_send_sync_msg(ar, mode);
491         if (ret) {
492                 ath10k_err(ar, "failed to send qmi mode: %d\n", ret);
493                 return ret;
494         }
495
496         return 0;
497 }
498
499 int ath10k_qmi_wlan_disable(struct ath10k *ar)
500 {
501         return ath10k_qmi_mode_send_sync_msg(ar, QMI_WLFW_OFF_V01);
502 }
503
504 static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi)
505 {
506         struct wlfw_cap_resp_msg_v01 *resp;
507         struct wlfw_cap_req_msg_v01 req = {};
508         struct ath10k *ar = qmi->ar;
509         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
510         struct qmi_txn txn;
511         int ret;
512
513         resp = kzalloc(sizeof(*resp), GFP_KERNEL);
514         if (!resp)
515                 return -ENOMEM;
516
517         ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cap_resp_msg_v01_ei, resp);
518         if (ret < 0)
519                 goto out;
520
521         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
522                                QMI_WLFW_CAP_REQ_V01,
523                                WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN,
524                                wlfw_cap_req_msg_v01_ei, &req);
525         if (ret < 0) {
526                 qmi_txn_cancel(&txn);
527                 ath10k_err(ar, "failed to send capability request: %d\n", ret);
528                 goto out;
529         }
530
531         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
532         if (ret < 0)
533                 goto out;
534
535         if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
536                 ath10k_err(ar, "capability req rejected: %d\n", resp->resp.error);
537                 ret = -EINVAL;
538                 goto out;
539         }
540
541         if (resp->chip_info_valid) {
542                 qmi->chip_info.chip_id = resp->chip_info.chip_id;
543                 qmi->chip_info.chip_family = resp->chip_info.chip_family;
544         }
545
546         if (resp->board_info_valid)
547                 qmi->board_info.board_id = resp->board_info.board_id;
548         else
549                 qmi->board_info.board_id = 0xFF;
550
551         if (resp->soc_info_valid)
552                 qmi->soc_info.soc_id = resp->soc_info.soc_id;
553
554         if (resp->fw_version_info_valid) {
555                 qmi->fw_version = resp->fw_version_info.fw_version;
556                 strlcpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp,
557                         sizeof(qmi->fw_build_timestamp));
558         }
559
560         if (resp->fw_build_id_valid)
561                 strlcpy(qmi->fw_build_id, resp->fw_build_id,
562                         MAX_BUILD_ID_LEN + 1);
563
564         if (!test_bit(ATH10K_SNOC_FLAG_REGISTERED, &ar_snoc->flags)) {
565                 ath10k_info(ar, "qmi chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x",
566                             qmi->chip_info.chip_id, qmi->chip_info.chip_family,
567                             qmi->board_info.board_id, qmi->soc_info.soc_id);
568                 ath10k_info(ar, "qmi fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
569                             qmi->fw_version, qmi->fw_build_timestamp, qmi->fw_build_id);
570         }
571
572         kfree(resp);
573         return 0;
574
575 out:
576         kfree(resp);
577         return ret;
578 }
579
580 static int ath10k_qmi_host_cap_send_sync(struct ath10k_qmi *qmi)
581 {
582         struct wlfw_host_cap_resp_msg_v01 resp = {};
583         struct wlfw_host_cap_req_msg_v01 req = {};
584         struct ath10k *ar = qmi->ar;
585         struct qmi_txn txn;
586         int ret;
587
588         req.daemon_support_valid = 1;
589         req.daemon_support = 0;
590
591         ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
592                            wlfw_host_cap_resp_msg_v01_ei, &resp);
593         if (ret < 0)
594                 goto out;
595
596         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
597                                QMI_WLFW_HOST_CAP_REQ_V01,
598                                WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN,
599                                wlfw_host_cap_req_msg_v01_ei, &req);
600         if (ret < 0) {
601                 qmi_txn_cancel(&txn);
602                 ath10k_err(ar, "failed to send host capability request: %d\n", ret);
603                 goto out;
604         }
605
606         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
607         if (ret < 0)
608                 goto out;
609
610         if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
611                 ath10k_err(ar, "host capability request rejected: %d\n", resp.resp.error);
612                 ret = -EINVAL;
613                 goto out;
614         }
615
616         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi host capability request completed\n");
617         return 0;
618
619 out:
620         return ret;
621 }
622
623 int ath10k_qmi_set_fw_log_mode(struct ath10k *ar, u8 fw_log_mode)
624 {
625         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
626         struct wlfw_ini_resp_msg_v01 resp = {};
627         struct ath10k_qmi *qmi = ar_snoc->qmi;
628         struct wlfw_ini_req_msg_v01 req = {};
629         struct qmi_txn txn;
630         int ret;
631
632         req.enablefwlog_valid = 1;
633         req.enablefwlog = fw_log_mode;
634
635         ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_ini_resp_msg_v01_ei,
636                            &resp);
637         if (ret < 0)
638                 goto out;
639
640         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
641                                QMI_WLFW_INI_REQ_V01,
642                                WLFW_INI_REQ_MSG_V01_MAX_MSG_LEN,
643                                wlfw_ini_req_msg_v01_ei, &req);
644         if (ret < 0) {
645                 qmi_txn_cancel(&txn);
646                 ath10k_err(ar, "fail to send fw log reqest: %d\n", ret);
647                 goto out;
648         }
649
650         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
651         if (ret < 0)
652                 goto out;
653
654         if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
655                 ath10k_err(ar, "fw log request rejectedr: %d\n",
656                            resp.resp.error);
657                 ret = -EINVAL;
658                 goto out;
659         }
660         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi fw log request completed, mode: %d\n",
661                    fw_log_mode);
662         return 0;
663
664 out:
665         return ret;
666 }
667
668 static int
669 ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi)
670 {
671         struct wlfw_ind_register_resp_msg_v01 resp = {};
672         struct wlfw_ind_register_req_msg_v01 req = {};
673         struct ath10k *ar = qmi->ar;
674         struct qmi_txn txn;
675         int ret;
676
677         req.client_id_valid = 1;
678         req.client_id = ATH10K_QMI_CLIENT_ID;
679         req.fw_ready_enable_valid = 1;
680         req.fw_ready_enable = 1;
681         req.msa_ready_enable_valid = 1;
682         req.msa_ready_enable = 1;
683
684         ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
685                            wlfw_ind_register_resp_msg_v01_ei, &resp);
686         if (ret < 0)
687                 goto out;
688
689         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
690                                QMI_WLFW_IND_REGISTER_REQ_V01,
691                                WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN,
692                                wlfw_ind_register_req_msg_v01_ei, &req);
693         if (ret < 0) {
694                 qmi_txn_cancel(&txn);
695                 ath10k_err(ar, "failed to send indication registered request: %d\n", ret);
696                 goto out;
697         }
698
699         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
700         if (ret < 0)
701                 goto out;
702
703         if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
704                 ath10k_err(ar, "indication request rejected: %d\n", resp.resp.error);
705                 ret = -EINVAL;
706                 goto out;
707         }
708
709         if (resp.fw_status_valid) {
710                 if (resp.fw_status & QMI_WLFW_FW_READY_V01)
711                         qmi->fw_ready = true;
712         }
713         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi indication register request completed\n");
714         return 0;
715
716 out:
717         return ret;
718 }
719
720 static void ath10k_qmi_event_server_arrive(struct ath10k_qmi *qmi)
721 {
722         struct ath10k *ar = qmi->ar;
723         int ret;
724
725         ret = ath10k_qmi_ind_register_send_sync_msg(qmi);
726         if (ret)
727                 return;
728
729         if (qmi->fw_ready) {
730                 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND);
731                 return;
732         }
733
734         ret = ath10k_qmi_host_cap_send_sync(qmi);
735         if (ret)
736                 return;
737
738         ret = ath10k_qmi_msa_mem_info_send_sync_msg(qmi);
739         if (ret)
740                 return;
741
742         ret = ath10k_qmi_setup_msa_permissions(qmi);
743         if (ret)
744                 return;
745
746         ret = ath10k_qmi_msa_ready_send_sync_msg(qmi);
747         if (ret)
748                 goto err_setup_msa;
749
750         ret = ath10k_qmi_cap_send_sync_msg(qmi);
751         if (ret)
752                 goto err_setup_msa;
753
754         return;
755
756 err_setup_msa:
757         ath10k_qmi_remove_msa_permission(qmi);
758 }
759
760 static int ath10k_qmi_fetch_board_file(struct ath10k_qmi *qmi)
761 {
762         struct ath10k *ar = qmi->ar;
763
764         ar->hif.bus = ATH10K_BUS_SNOC;
765         ar->id.qmi_ids_valid = true;
766         ar->id.qmi_board_id = qmi->board_info.board_id;
767         ar->hw_params.fw.dir = WCN3990_HW_1_0_FW_DIR;
768
769         return ath10k_core_fetch_board_file(qmi->ar, ATH10K_BD_IE_BOARD);
770 }
771
772 static int
773 ath10k_qmi_driver_event_post(struct ath10k_qmi *qmi,
774                              enum ath10k_qmi_driver_event_type type,
775                              void *data)
776 {
777         struct ath10k_qmi_driver_event *event;
778
779         event = kzalloc(sizeof(*event), GFP_ATOMIC);
780         if (!event)
781                 return -ENOMEM;
782
783         event->type = type;
784         event->data = data;
785
786         spin_lock(&qmi->event_lock);
787         list_add_tail(&event->list, &qmi->event_list);
788         spin_unlock(&qmi->event_lock);
789
790         queue_work(qmi->event_wq, &qmi->event_work);
791
792         return 0;
793 }
794
795 static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi)
796 {
797         struct ath10k *ar = qmi->ar;
798
799         ath10k_qmi_remove_msa_permission(qmi);
800         ath10k_core_free_board_files(ar);
801         ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND);
802         ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service disconnected\n");
803 }
804
805 static void ath10k_qmi_event_msa_ready(struct ath10k_qmi *qmi)
806 {
807         int ret;
808
809         ret = ath10k_qmi_fetch_board_file(qmi);
810         if (ret)
811                 goto out;
812
813         ret = ath10k_qmi_bdf_dnld_send_sync(qmi);
814         if (ret)
815                 goto out;
816
817         ret = ath10k_qmi_send_cal_report_req(qmi);
818
819 out:
820         return;
821 }
822
823 static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi)
824 {
825         struct ath10k *ar = qmi->ar;
826
827         ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw ready event received\n");
828         ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND);
829
830         return 0;
831 }
832
833 static void ath10k_qmi_fw_ready_ind(struct qmi_handle *qmi_hdl,
834                                     struct sockaddr_qrtr *sq,
835                                     struct qmi_txn *txn, const void *data)
836 {
837         struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
838
839         ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_FW_READY_IND, NULL);
840 }
841
842 static void ath10k_qmi_msa_ready_ind(struct qmi_handle *qmi_hdl,
843                                      struct sockaddr_qrtr *sq,
844                                      struct qmi_txn *txn, const void *data)
845 {
846         struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
847
848         ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_MSA_READY_IND, NULL);
849 }
850
851 static struct qmi_msg_handler qmi_msg_handler[] = {
852         {
853                 .type = QMI_INDICATION,
854                 .msg_id = QMI_WLFW_FW_READY_IND_V01,
855                 .ei = wlfw_fw_ready_ind_msg_v01_ei,
856                 .decoded_size = sizeof(struct wlfw_fw_ready_ind_msg_v01),
857                 .fn = ath10k_qmi_fw_ready_ind,
858         },
859         {
860                 .type = QMI_INDICATION,
861                 .msg_id = QMI_WLFW_MSA_READY_IND_V01,
862                 .ei = wlfw_msa_ready_ind_msg_v01_ei,
863                 .decoded_size = sizeof(struct wlfw_msa_ready_ind_msg_v01),
864                 .fn = ath10k_qmi_msa_ready_ind,
865         },
866         {}
867 };
868
869 static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl,
870                                  struct qmi_service *service)
871 {
872         struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
873         struct sockaddr_qrtr *sq = &qmi->sq;
874         struct ath10k *ar = qmi->ar;
875         int ret;
876
877         sq->sq_family = AF_QIPCRTR;
878         sq->sq_node = service->node;
879         sq->sq_port = service->port;
880
881         ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service found\n");
882
883         ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)&qmi->sq,
884                              sizeof(qmi->sq), 0);
885         if (ret) {
886                 ath10k_err(ar, "failed to connect to a remote QMI service port\n");
887                 return ret;
888         }
889
890         ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wifi fw qmi service connected\n");
891         ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_ARRIVE, NULL);
892
893         return ret;
894 }
895
896 static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl,
897                                   struct qmi_service *service)
898 {
899         struct ath10k_qmi *qmi =
900                 container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
901
902         qmi->fw_ready = false;
903         ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, NULL);
904 }
905
906 static struct qmi_ops ath10k_qmi_ops = {
907         .new_server = ath10k_qmi_new_server,
908         .del_server = ath10k_qmi_del_server,
909 };
910
911 static void ath10k_qmi_driver_event_work(struct work_struct *work)
912 {
913         struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi,
914                                               event_work);
915         struct ath10k_qmi_driver_event *event;
916         struct ath10k *ar = qmi->ar;
917
918         spin_lock(&qmi->event_lock);
919         while (!list_empty(&qmi->event_list)) {
920                 event = list_first_entry(&qmi->event_list,
921                                          struct ath10k_qmi_driver_event, list);
922                 list_del(&event->list);
923                 spin_unlock(&qmi->event_lock);
924
925                 switch (event->type) {
926                 case ATH10K_QMI_EVENT_SERVER_ARRIVE:
927                         ath10k_qmi_event_server_arrive(qmi);
928                         break;
929                 case ATH10K_QMI_EVENT_SERVER_EXIT:
930                         ath10k_qmi_event_server_exit(qmi);
931                         break;
932                 case ATH10K_QMI_EVENT_FW_READY_IND:
933                         ath10k_qmi_event_fw_ready_ind(qmi);
934                         break;
935                 case ATH10K_QMI_EVENT_MSA_READY_IND:
936                         ath10k_qmi_event_msa_ready(qmi);
937                         break;
938                 default:
939                         ath10k_warn(ar, "invalid event type: %d", event->type);
940                         break;
941                 }
942                 kfree(event);
943                 spin_lock(&qmi->event_lock);
944         }
945         spin_unlock(&qmi->event_lock);
946 }
947
948 static int ath10k_qmi_setup_msa_resources(struct ath10k_qmi *qmi, u32 msa_size)
949 {
950         struct ath10k *ar = qmi->ar;
951         struct device *dev = ar->dev;
952         struct device_node *node;
953         struct resource r;
954         int ret;
955
956         node = of_parse_phandle(dev->of_node, "memory-region", 0);
957         if (node) {
958                 ret = of_address_to_resource(node, 0, &r);
959                 if (ret) {
960                         dev_err(dev, "failed to resolve msa fixed region\n");
961                         return ret;
962                 }
963                 of_node_put(node);
964
965                 qmi->msa_pa = r.start;
966                 qmi->msa_mem_size = resource_size(&r);
967                 qmi->msa_va = devm_memremap(dev, qmi->msa_pa, qmi->msa_mem_size,
968                                             MEMREMAP_WT);
969                 if (IS_ERR(qmi->msa_va)) {
970                         dev_err(dev, "failed to map memory region: %pa\n", &r.start);
971                         return PTR_ERR(qmi->msa_va);
972                 }
973         } else {
974                 qmi->msa_va = dmam_alloc_coherent(dev, msa_size,
975                                                   &qmi->msa_pa, GFP_KERNEL);
976                 if (!qmi->msa_va) {
977                         ath10k_err(ar, "failed to allocate dma memory for msa region\n");
978                         return -ENOMEM;
979                 }
980                 qmi->msa_mem_size = msa_size;
981         }
982
983         ath10k_dbg(ar, ATH10K_DBG_QMI, "msa pa: %pad , msa va: 0x%p\n",
984                    &qmi->msa_pa,
985                    qmi->msa_va);
986
987         return 0;
988 }
989
990 int ath10k_qmi_init(struct ath10k *ar, u32 msa_size)
991 {
992         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
993         struct ath10k_qmi *qmi;
994         int ret;
995
996         qmi = kzalloc(sizeof(*qmi), GFP_KERNEL);
997         if (!qmi)
998                 return -ENOMEM;
999
1000         qmi->ar = ar;
1001         ar_snoc->qmi = qmi;
1002
1003         ret = ath10k_qmi_setup_msa_resources(qmi, msa_size);
1004         if (ret)
1005                 goto err;
1006
1007         ret = qmi_handle_init(&qmi->qmi_hdl,
1008                               WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
1009                               &ath10k_qmi_ops, qmi_msg_handler);
1010         if (ret)
1011                 goto err;
1012
1013         qmi->event_wq = alloc_workqueue("ath10k_qmi_driver_event",
1014                                         WQ_UNBOUND, 1);
1015         if (!qmi->event_wq) {
1016                 ath10k_err(ar, "failed to allocate workqueue\n");
1017                 ret = -EFAULT;
1018                 goto err_release_qmi_handle;
1019         }
1020
1021         INIT_LIST_HEAD(&qmi->event_list);
1022         spin_lock_init(&qmi->event_lock);
1023         INIT_WORK(&qmi->event_work, ath10k_qmi_driver_event_work);
1024
1025         ret = qmi_add_lookup(&qmi->qmi_hdl, WLFW_SERVICE_ID_V01,
1026                              WLFW_SERVICE_VERS_V01, 0);
1027         if (ret)
1028                 goto err_qmi_lookup;
1029
1030         return 0;
1031
1032 err_qmi_lookup:
1033         destroy_workqueue(qmi->event_wq);
1034
1035 err_release_qmi_handle:
1036         qmi_handle_release(&qmi->qmi_hdl);
1037
1038 err:
1039         kfree(qmi);
1040         return ret;
1041 }
1042
1043 int ath10k_qmi_deinit(struct ath10k *ar)
1044 {
1045         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1046         struct ath10k_qmi *qmi = ar_snoc->qmi;
1047
1048         qmi_handle_release(&qmi->qmi_hdl);
1049         cancel_work_sync(&qmi->event_work);
1050         destroy_workqueue(qmi->event_wq);
1051         kfree(qmi);
1052         ar_snoc->qmi = NULL;
1053
1054         return 0;
1055 }