qmi.c 27 KB

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