ipa_qmi_service.c 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/module.h>
  6. #include <linux/slab.h>
  7. #include <linux/errno.h>
  8. #include <linux/delay.h>
  9. #include <linux/debugfs.h>
  10. #include <linux/delay.h>
  11. #include <linux/uaccess.h>
  12. #include <soc/qcom/subsystem_restart.h>
  13. #include <linux/ipa.h>
  14. #include <linux/vmalloc.h>
  15. #include "ipa_qmi_service.h"
  16. #include "ipa_mhi_proxy.h"
  17. #define IPA_Q6_SVC_VERS 1
  18. #define IPA_A5_SVC_VERS 1
  19. #define Q6_QMI_COMPLETION_TIMEOUT (60*HZ)
  20. #define IPA_A5_SERVICE_SVC_ID 0x31
  21. #define IPA_A5_SERVICE_INS_ID 1
  22. #define IPA_Q6_SERVICE_SVC_ID 0x31
  23. #define IPA_Q6_SERVICE_INS_ID 2
  24. #define QMI_SEND_STATS_REQ_TIMEOUT_MS 5000
  25. #define QMI_SEND_REQ_TIMEOUT_MS 60000
  26. #define QMI_MHI_SEND_REQ_TIMEOUT_MS 1000
  27. #define QMI_IPA_FORCE_CLEAR_DATAPATH_TIMEOUT_MS 1000
  28. static struct qmi_handle *ipa3_svc_handle;
  29. static struct workqueue_struct *ipa_clnt_req_workqueue;
  30. static bool ipa3_qmi_modem_init_fin, ipa3_qmi_indication_fin;
  31. static struct work_struct ipa3_qmi_service_init_work;
  32. static uint32_t ipa_wan_platform;
  33. struct ipa3_qmi_context *ipa3_qmi_ctx;
  34. static bool workqueues_stopped;
  35. static bool ipa3_modem_init_cmplt;
  36. static bool first_time_handshake;
  37. static bool send_qmi_init_q6;
  38. struct mutex ipa3_qmi_lock;
  39. struct ipa_msg_desc {
  40. uint16_t msg_id;
  41. int max_msg_len;
  42. struct qmi_elem_info *ei_array;
  43. };
  44. static struct ipa_mhi_prime_aggr_info_req_msg_v01 aggr_req = {
  45. .aggr_info_valid = 1,
  46. .aggr_info_len = 5,
  47. .aggr_info[0] = {
  48. .ic_type = DATA_IC_TYPE_MHI_PRIME_V01,
  49. .ep_type = DATA_EP_DESC_TYPE_DPL_PROD_V01,
  50. .bytes_count = 16,
  51. },
  52. .aggr_info[1] = {
  53. .ic_type = DATA_IC_TYPE_MHI_PRIME_V01,
  54. .ep_type = DATA_EP_DESC_TYPE_TETH_CONS_V01,
  55. .bytes_count = 24,
  56. .aggr_type = DATA_AGGR_TYPE_QMAPv5_V01,
  57. },
  58. .aggr_info[2] = {
  59. .ic_type = DATA_IC_TYPE_MHI_PRIME_V01,
  60. .ep_type = DATA_EP_DESC_TYPE_TETH_PROD_V01,
  61. .bytes_count = 16,
  62. .aggr_type = DATA_AGGR_TYPE_QMAPv5_V01,
  63. },
  64. .aggr_info[3] = {
  65. .ic_type = DATA_IC_TYPE_MHI_PRIME_V01,
  66. .ep_type = DATA_EP_DESC_TYPE_TETH_RMNET_CONS_V01,
  67. .bytes_count = 31,
  68. .aggr_type = DATA_AGGR_TYPE_QMAPv5_V01,
  69. },
  70. .aggr_info[4] = {
  71. .ic_type = DATA_IC_TYPE_MHI_PRIME_V01,
  72. .ep_type = DATA_EP_DESC_TYPE_TETH_RMNET_PROD_V01,
  73. .bytes_count = 31,
  74. .aggr_type = DATA_AGGR_TYPE_QMAPv5_V01,
  75. },
  76. };
  77. /* QMI A5 service */
  78. static void ipa3_handle_indication_req(struct qmi_handle *qmi_handle,
  79. struct sockaddr_qrtr *sq,
  80. struct qmi_txn *txn,
  81. const void *decoded_msg)
  82. {
  83. struct ipa_indication_reg_req_msg_v01 *indication_req;
  84. struct ipa_indication_reg_resp_msg_v01 resp;
  85. struct ipa_master_driver_init_complt_ind_msg_v01 ind;
  86. int rc;
  87. indication_req = (struct ipa_indication_reg_req_msg_v01 *)decoded_msg;
  88. IPAWANDBG("Received INDICATION Request\n");
  89. /* cache the client sq */
  90. memcpy(&ipa3_qmi_ctx->client_sq, sq, sizeof(*sq));
  91. memset(&resp, 0, sizeof(struct ipa_indication_reg_resp_msg_v01));
  92. resp.resp.result = IPA_QMI_RESULT_SUCCESS_V01;
  93. IPAWANDBG("qmi_snd_rsp: result %d, err %d\n",
  94. resp.resp.result, resp.resp.error);
  95. rc = qmi_send_response(qmi_handle, sq, txn,
  96. QMI_IPA_INDICATION_REGISTER_RESP_V01,
  97. QMI_IPA_INDICATION_REGISTER_RESP_MAX_MSG_LEN_V01,
  98. ipa3_indication_reg_resp_msg_data_v01_ei,
  99. &resp);
  100. if (rc < 0) {
  101. IPAWANERR("send response for Indication register failed\n");
  102. return;
  103. }
  104. ipa3_qmi_indication_fin = true;
  105. /* check if need sending indication to modem */
  106. if (ipa3_qmi_modem_init_fin) {
  107. IPAWANDBG("send indication to modem (%d)\n",
  108. ipa3_qmi_modem_init_fin);
  109. memset(&ind, 0, sizeof(struct
  110. ipa_master_driver_init_complt_ind_msg_v01));
  111. ind.master_driver_init_status.result =
  112. IPA_QMI_RESULT_SUCCESS_V01;
  113. rc = qmi_send_indication(qmi_handle,
  114. &(ipa3_qmi_ctx->client_sq),
  115. QMI_IPA_MASTER_DRIVER_INIT_COMPLETE_IND_V01,
  116. QMI_IPA_MASTER_DRIVER_INIT_COMPLETE_IND_MAX_MSG_LEN_V01,
  117. ipa3_master_driver_init_complt_ind_msg_data_v01_ei,
  118. &ind);
  119. if (rc < 0) {
  120. IPAWANERR("send indication failed\n");
  121. ipa3_qmi_indication_fin = false;
  122. }
  123. } else {
  124. IPAWANERR("not send indication\n");
  125. }
  126. }
  127. static void ipa3_handle_install_filter_rule_req(struct qmi_handle *qmi_handle,
  128. struct sockaddr_qrtr *sq,
  129. struct qmi_txn *txn,
  130. const void *decoded_msg)
  131. {
  132. struct ipa_install_fltr_rule_req_msg_v01 *rule_req;
  133. struct ipa_install_fltr_rule_resp_msg_v01 resp;
  134. uint32_t rule_hdl[MAX_NUM_Q6_RULE];
  135. int rc = 0, i;
  136. rule_req = (struct ipa_install_fltr_rule_req_msg_v01 *)decoded_msg;
  137. memset(rule_hdl, 0, sizeof(rule_hdl));
  138. memset(&resp, 0, sizeof(struct ipa_install_fltr_rule_resp_msg_v01));
  139. IPAWANDBG("Received install filter Request\n");
  140. rc = ipa3_copy_ul_filter_rule_to_ipa((struct
  141. ipa_install_fltr_rule_req_msg_v01*)decoded_msg);
  142. if (rc) {
  143. IPAWANERR("copy UL rules from modem is failed\n");
  144. return;
  145. }
  146. resp.resp.result = IPA_QMI_RESULT_SUCCESS_V01;
  147. if (rule_req->filter_spec_ex_list_valid == true) {
  148. resp.rule_id_valid = 1;
  149. if (rule_req->filter_spec_ex_list_len > MAX_NUM_Q6_RULE) {
  150. resp.rule_id_len = MAX_NUM_Q6_RULE;
  151. IPAWANERR("installed (%d) max Q6-UL rules ",
  152. MAX_NUM_Q6_RULE);
  153. IPAWANERR("but modem gives total (%u)\n",
  154. rule_req->filter_spec_ex_list_len);
  155. } else {
  156. resp.rule_id_len =
  157. rule_req->filter_spec_ex_list_len;
  158. }
  159. } else {
  160. resp.rule_id_valid = 0;
  161. resp.rule_id_len = 0;
  162. }
  163. /* construct UL filter rules response to Modem*/
  164. for (i = 0; i < resp.rule_id_len; i++) {
  165. resp.rule_id[i] =
  166. rule_req->filter_spec_ex_list[i].rule_id;
  167. }
  168. IPAWANDBG("qmi_snd_rsp: result %d, err %d\n",
  169. resp.resp.result, resp.resp.error);
  170. rc = qmi_send_response(qmi_handle, sq, txn,
  171. QMI_IPA_INSTALL_FILTER_RULE_RESP_V01,
  172. QMI_IPA_INSTALL_FILTER_RULE_RESP_MAX_MSG_LEN_V01,
  173. ipa3_install_fltr_rule_resp_msg_data_v01_ei,
  174. &resp);
  175. if (rc < 0)
  176. IPAWANERR("install filter rules failed\n");
  177. else
  178. IPAWANDBG("Replied to install filter request\n");
  179. }
  180. static void ipa3_handle_filter_installed_notify_req(
  181. struct qmi_handle *qmi_handle,
  182. struct sockaddr_qrtr *sq,
  183. struct qmi_txn *txn,
  184. const void *decoded_msg)
  185. {
  186. struct ipa_fltr_installed_notif_resp_msg_v01 resp;
  187. int rc = 0;
  188. memset(&resp, 0, sizeof(struct ipa_fltr_installed_notif_resp_msg_v01));
  189. IPAWANDBG("Received filter_install_notify Request\n");
  190. resp.resp.result = IPA_QMI_RESULT_SUCCESS_V01;
  191. IPAWANDBG("qmi_snd_rsp: result %d, err %d\n",
  192. resp.resp.result, resp.resp.error);
  193. rc = qmi_send_response(qmi_handle, sq, txn,
  194. QMI_IPA_FILTER_INSTALLED_NOTIF_RESP_V01,
  195. QMI_IPA_FILTER_INSTALLED_NOTIF_RESP_MAX_MSG_LEN_V01,
  196. ipa3_fltr_installed_notif_resp_msg_data_v01_ei,
  197. &resp);
  198. if (rc < 0)
  199. IPAWANERR("handle filter rules failed\n");
  200. else
  201. IPAWANDBG("Responsed filter_install_notify Request\n");
  202. }
  203. static void handle_ipa_config_req(struct qmi_handle *qmi_handle,
  204. struct sockaddr_qrtr *sq,
  205. struct qmi_txn *txn,
  206. const void *decoded_msg)
  207. {
  208. struct ipa_config_resp_msg_v01 resp;
  209. int rc;
  210. memset(&resp, 0, sizeof(struct ipa_config_resp_msg_v01));
  211. resp.resp.result = IPA_QMI_RESULT_SUCCESS_V01;
  212. IPAWANDBG("Received IPA CONFIG Request\n");
  213. rc = ipa_mhi_handle_ipa_config_req(
  214. (struct ipa_config_req_msg_v01 *)decoded_msg);
  215. if (rc) {
  216. IPAERR("ipa3_mhi_handle_ipa_config_req failed %d\n", rc);
  217. resp.resp.result = IPA_QMI_RESULT_FAILURE_V01;
  218. }
  219. IPAWANDBG("qmi_snd_rsp: result %d, err %d\n",
  220. resp.resp.result, resp.resp.error);
  221. rc = qmi_send_response(qmi_handle, sq, txn,
  222. QMI_IPA_CONFIG_RESP_V01,
  223. QMI_IPA_CONFIG_RESP_MAX_MSG_LEN_V01,
  224. ipa3_config_resp_msg_data_v01_ei,
  225. &resp);
  226. if (rc < 0)
  227. IPAWANERR("QMI_IPA_CONFIG_RESP_V01 failed\n");
  228. else
  229. IPAWANDBG("Responsed QMI_IPA_CONFIG_RESP_V01\n");
  230. }
  231. static void ipa3_handle_modem_init_cmplt_req(struct qmi_handle *qmi_handle,
  232. struct sockaddr_qrtr *sq,
  233. struct qmi_txn *txn,
  234. const void *decoded_msg)
  235. {
  236. struct ipa_init_modem_driver_cmplt_req_msg_v01 *cmplt_req;
  237. struct ipa_init_modem_driver_cmplt_resp_msg_v01 resp;
  238. int rc;
  239. IPAWANDBG("Received QMI_IPA_INIT_MODEM_DRIVER_CMPLT_REQ_V01\n");
  240. cmplt_req = (struct ipa_init_modem_driver_cmplt_req_msg_v01 *)
  241. decoded_msg;
  242. if (!ipa3_modem_init_cmplt) {
  243. ipa3_modem_init_cmplt = true;
  244. }
  245. memset(&resp, 0, sizeof(resp));
  246. resp.resp.result = IPA_QMI_RESULT_SUCCESS_V01;
  247. IPAWANDBG("qmi_snd_rsp: result %d, err %d\n",
  248. resp.resp.result, resp.resp.error);
  249. rc = qmi_send_response(qmi_handle, sq, txn,
  250. QMI_IPA_INIT_MODEM_DRIVER_CMPLT_RESP_V01,
  251. QMI_IPA_INIT_MODEM_DRIVER_CMPLT_RESP_MAX_MSG_LEN_V01,
  252. ipa3_init_modem_driver_cmplt_resp_msg_data_v01_ei,
  253. &resp);
  254. if (rc < 0)
  255. IPAWANERR("QMI_IPA_INIT_MODEM_DRIVER_CMPLT_RESP_V01 failed\n");
  256. else
  257. IPAWANDBG("Sent QMI_IPA_INIT_MODEM_DRIVER_CMPLT_RESP_V01\n");
  258. }
  259. static void ipa3_handle_mhi_alloc_channel_req(struct qmi_handle *qmi_handle,
  260. struct sockaddr_qrtr *sq,
  261. struct qmi_txn *txn,
  262. const void *decoded_msg)
  263. {
  264. struct ipa_mhi_alloc_channel_req_msg_v01 *ch_alloc_req;
  265. struct ipa_mhi_alloc_channel_resp_msg_v01 *resp = NULL;
  266. int rc;
  267. IPAWANDBG("Received QMI_IPA_MHI_ALLOC_CHANNEL_REQ_V01\n");
  268. ch_alloc_req = (struct ipa_mhi_alloc_channel_req_msg_v01 *)decoded_msg;
  269. resp = imp_handle_allocate_channel_req(ch_alloc_req);
  270. if (!resp) {
  271. IPAWANERR("imp handle allocate channel req fails\n");
  272. return;
  273. }
  274. IPAWANDBG("qmi_snd_rsp: result %d, err %d, arr_vald: %d, arr_len %d\n",
  275. resp->resp.result, resp->resp.error, resp->alloc_resp_arr_valid,
  276. resp->alloc_resp_arr_len);
  277. rc = qmi_send_response(qmi_handle, sq, txn,
  278. QMI_IPA_MHI_ALLOC_CHANNEL_RESP_V01,
  279. IPA_MHI_ALLOC_CHANNEL_RESP_MSG_V01_MAX_MSG_LEN,
  280. ipa_mhi_alloc_channel_resp_msg_v01_ei,
  281. resp);
  282. if (rc < 0)
  283. IPAWANERR("QMI_IPA_MHI_ALLOC_CHANNEL_RESP_V01 failed\n");
  284. else
  285. IPAWANDBG("Sent QMI_IPA_MHI_ALLOC_CHANNEL_RESP_V01\n");
  286. }
  287. static void ipa3_handle_mhi_vote_req(struct qmi_handle *qmi_handle,
  288. struct sockaddr_qrtr *sq,
  289. struct qmi_txn *txn,
  290. const void *decoded_msg)
  291. {
  292. struct ipa_mhi_clk_vote_req_msg_v01 *vote_req;
  293. struct ipa_mhi_clk_vote_resp_msg_v01 *resp = NULL, resp2;
  294. int rc;
  295. uint32_t bw_mbps = 0;
  296. vote_req = (struct ipa_mhi_clk_vote_req_msg_v01 *)decoded_msg;
  297. IPAWANDBG("Received QMI_IPA_MHI_CLK_VOTE_REQ_V01(%d)\n",
  298. vote_req->mhi_vote);
  299. memset(&resp2, 0, sizeof(struct ipa_mhi_clk_vote_resp_msg_v01));
  300. /* for mpm used for ipa clk voting */
  301. if (ipa3_is_apq()) {
  302. IPAWANDBG("Throughput(%d:%d) clk-rate(%d:%d)\n",
  303. vote_req->tput_value_valid,
  304. vote_req->tput_value,
  305. vote_req->clk_rate_valid,
  306. vote_req->clk_rate);
  307. if (vote_req->clk_rate_valid) {
  308. switch (vote_req->clk_rate) {
  309. case QMI_IPA_CLOCK_RATE_LOW_SVS_V01:
  310. bw_mbps = 0;
  311. break;
  312. case QMI_IPA_CLOCK_RATE_SVS_V01:
  313. bw_mbps = 350;
  314. break;
  315. case QMI_IPA_CLOCK_RATE_NOMINAL_V01:
  316. bw_mbps = 690;
  317. break;
  318. case QMI_IPA_CLOCK_RATE_TURBO_V01:
  319. bw_mbps = 1200;
  320. break;
  321. default:
  322. IPAWANERR("Note supported clk_rate (%d)\n",
  323. vote_req->clk_rate);
  324. bw_mbps = 0;
  325. resp2.resp.result = IPA_QMI_RESULT_FAILURE_V01;
  326. resp2.resp.error =
  327. IPA_QMI_ERR_NOT_SUPPORTED_V01;
  328. break;
  329. }
  330. if (ipa3_vote_for_bus_bw(&bw_mbps)) {
  331. IPAWANERR("Failed to vote BW (%u)\n", bw_mbps);
  332. resp2.resp.result = IPA_QMI_RESULT_FAILURE_V01;
  333. resp2.resp.error =
  334. IPA_QMI_ERR_NOT_SUPPORTED_V01;
  335. }
  336. resp = &resp2;
  337. }
  338. } else {
  339. resp = imp_handle_vote_req(vote_req->mhi_vote);
  340. if (!resp) {
  341. IPAWANERR("imp handle allocate channel req fails");
  342. return;
  343. }
  344. IPAWANDBG("start sending QMI_IPA_MHI_CLK_VOTE_RESP_V01\n");
  345. }
  346. IPAWANDBG("qmi_snd_rsp: result %d, err %d\n",
  347. resp->resp.result, resp->resp.error);
  348. rc = qmi_send_response(qmi_handle, sq, txn,
  349. QMI_IPA_MHI_CLK_VOTE_RESP_V01,
  350. IPA_MHI_CLK_VOTE_RESP_MSG_V01_MAX_MSG_LEN,
  351. ipa_mhi_clk_vote_resp_msg_v01_ei,
  352. resp);
  353. if (rc < 0)
  354. IPAWANERR("QMI_IPA_MHI_CLK_VOTE_RESP_V01 failed\n");
  355. else
  356. IPAWANDBG("Finished senting QMI_IPA_MHI_CLK_VOTE_RESP_V01\n");
  357. }
  358. static void ipa3_a5_svc_disconnect_cb(struct qmi_handle *qmi,
  359. unsigned int node, unsigned int port)
  360. {
  361. IPAWANDBG_LOW("Received QMI client disconnect\n");
  362. }
  363. /****************************************************/
  364. /* QMI A5 client ->Q6 */
  365. /****************************************************/
  366. static void ipa3_q6_clnt_svc_arrive(struct work_struct *work);
  367. static DECLARE_DELAYED_WORK(ipa3_work_svc_arrive, ipa3_q6_clnt_svc_arrive);
  368. static void ipa3_q6_clnt_svc_exit(struct work_struct *work);
  369. static DECLARE_DELAYED_WORK(ipa3_work_svc_exit, ipa3_q6_clnt_svc_exit);
  370. /* Test client port for IPC Router */
  371. static struct qmi_handle *ipa_q6_clnt;
  372. static int ipa3_check_qmi_response(int rc,
  373. int req_id,
  374. enum ipa_qmi_result_type_v01 result,
  375. enum ipa_qmi_error_type_v01 error,
  376. char *resp_type)
  377. {
  378. if (rc < 0) {
  379. if (rc == -ETIMEDOUT && ipa3_rmnet_ctx.ipa_rmnet_ssr) {
  380. IPAWANERR(
  381. "Timeout for qmi request id %d\n", req_id);
  382. return rc;
  383. }
  384. if ((rc == -ENETRESET) || (rc == -ENODEV)) {
  385. IPAWANERR(
  386. "SSR while waiting for qmi request id %d\n", req_id);
  387. return rc;
  388. }
  389. IPAWANERR("Error sending qmi request id %d, rc = %d\n",
  390. req_id, rc);
  391. return rc;
  392. }
  393. if (result != IPA_QMI_RESULT_SUCCESS_V01 &&
  394. ipa3_rmnet_ctx.ipa_rmnet_ssr) {
  395. IPAWANERR(
  396. "Got bad response %d from request id %d (error %d)\n",
  397. req_id, result, error);
  398. return result;
  399. }
  400. IPAWANDBG_LOW("Received %s successfully\n", resp_type);
  401. return 0;
  402. }
  403. static int ipa3_qmi_send_req_wait(struct qmi_handle *client_handle,
  404. struct ipa_msg_desc *req_desc, void *req,
  405. struct ipa_msg_desc *resp_desc, void *resp,
  406. unsigned long timeout_ms)
  407. {
  408. struct qmi_txn txn;
  409. int ret;
  410. ret = qmi_txn_init(client_handle, &txn, resp_desc->ei_array, resp);
  411. if (ret < 0) {
  412. IPAWANERR("QMI txn init failed, ret= %d\n", ret);
  413. return ret;
  414. }
  415. ret = qmi_send_request(client_handle,
  416. &ipa3_qmi_ctx->server_sq,
  417. &txn,
  418. req_desc->msg_id,
  419. req_desc->max_msg_len,
  420. req_desc->ei_array,
  421. req);
  422. if (ret < 0) {
  423. qmi_txn_cancel(&txn);
  424. return ret;
  425. }
  426. ret = qmi_txn_wait(&txn, msecs_to_jiffies(timeout_ms));
  427. return ret;
  428. }
  429. static int ipa3_qmi_init_modem_send_sync_msg(void)
  430. {
  431. struct ipa_init_modem_driver_req_msg_v01 req;
  432. struct ipa_init_modem_driver_resp_msg_v01 resp;
  433. struct ipa_msg_desc req_desc, resp_desc;
  434. int rc;
  435. u16 smem_restr_bytes = ipa3_get_smem_restr_bytes();
  436. int wan_cons_ep;
  437. memset(&req, 0, sizeof(struct ipa_init_modem_driver_req_msg_v01));
  438. memset(&resp, 0, sizeof(struct ipa_init_modem_driver_resp_msg_v01));
  439. req.platform_type_valid = true;
  440. req.platform_type = ipa_wan_platform;
  441. req.hdr_tbl_info_valid = (IPA_MEM_PART(modem_hdr_size) != 0);
  442. req.hdr_tbl_info.modem_offset_start =
  443. IPA_MEM_PART(modem_hdr_ofst) + smem_restr_bytes;
  444. req.hdr_tbl_info.modem_offset_end = IPA_MEM_PART(modem_hdr_ofst) +
  445. smem_restr_bytes + IPA_MEM_PART(modem_hdr_size) - 1;
  446. req.v4_route_tbl_info_valid = true;
  447. req.v4_route_tbl_info.route_tbl_start_addr =
  448. IPA_MEM_PART(v4_rt_nhash_ofst) + smem_restr_bytes;
  449. req.v4_route_tbl_info.num_indices =
  450. IPA_MEM_PART(v4_modem_rt_index_hi);
  451. req.v6_route_tbl_info_valid = true;
  452. req.v6_route_tbl_info.route_tbl_start_addr =
  453. IPA_MEM_PART(v6_rt_nhash_ofst) + smem_restr_bytes;
  454. req.v6_route_tbl_info.num_indices =
  455. IPA_MEM_PART(v6_modem_rt_index_hi);
  456. req.v4_filter_tbl_start_addr_valid = true;
  457. req.v4_filter_tbl_start_addr =
  458. IPA_MEM_PART(v4_flt_nhash_ofst) + smem_restr_bytes;
  459. req.v6_filter_tbl_start_addr_valid = true;
  460. req.v6_filter_tbl_start_addr =
  461. IPA_MEM_PART(v6_flt_nhash_ofst) + smem_restr_bytes;
  462. req.modem_mem_info_valid = (IPA_MEM_PART(modem_size) != 0);
  463. req.modem_mem_info.block_start_addr =
  464. IPA_MEM_PART(modem_ofst) + smem_restr_bytes;
  465. req.modem_mem_info.size = IPA_MEM_PART(modem_size);
  466. wan_cons_ep = ipa_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS);
  467. if (wan_cons_ep == IPA_EP_NOT_ALLOCATED) {
  468. IPAWANDBG("APPS_WAN_CONS is not valid\n");
  469. req.ctrl_comm_dest_end_pt_valid = false;
  470. req.ctrl_comm_dest_end_pt = 0;
  471. } else {
  472. req.ctrl_comm_dest_end_pt_valid = true;
  473. req.ctrl_comm_dest_end_pt =
  474. ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS);
  475. }
  476. req.hdr_proc_ctx_tbl_info_valid =
  477. (IPA_MEM_PART(modem_hdr_proc_ctx_size) != 0);
  478. req.hdr_proc_ctx_tbl_info.modem_offset_start =
  479. IPA_MEM_PART(modem_hdr_proc_ctx_ofst) + smem_restr_bytes;
  480. req.hdr_proc_ctx_tbl_info.modem_offset_end =
  481. IPA_MEM_PART(modem_hdr_proc_ctx_ofst) +
  482. IPA_MEM_PART(modem_hdr_proc_ctx_size) + smem_restr_bytes - 1;
  483. req.zip_tbl_info_valid = (IPA_MEM_PART(modem_comp_decomp_size) != 0);
  484. req.zip_tbl_info.modem_offset_start =
  485. IPA_MEM_PART(modem_comp_decomp_size) + smem_restr_bytes;
  486. req.zip_tbl_info.modem_offset_end =
  487. IPA_MEM_PART(modem_comp_decomp_ofst) +
  488. IPA_MEM_PART(modem_comp_decomp_size) + smem_restr_bytes - 1;
  489. /* if hashing not supported, Modem filter/routing hash
  490. * tables should not fill with valid data.
  491. */
  492. if (!ipa3_ctx->ipa_fltrt_not_hashable) {
  493. req.v4_hash_route_tbl_info_valid = true;
  494. req.v4_hash_route_tbl_info.route_tbl_start_addr =
  495. IPA_MEM_PART(v4_rt_hash_ofst) + smem_restr_bytes;
  496. req.v4_hash_route_tbl_info.num_indices =
  497. IPA_MEM_PART(v4_modem_rt_index_hi);
  498. req.v6_hash_route_tbl_info_valid = true;
  499. req.v6_hash_route_tbl_info.route_tbl_start_addr =
  500. IPA_MEM_PART(v6_rt_hash_ofst) + smem_restr_bytes;
  501. req.v6_hash_route_tbl_info.num_indices =
  502. IPA_MEM_PART(v6_modem_rt_index_hi);
  503. req.v4_hash_filter_tbl_start_addr_valid = true;
  504. req.v4_hash_filter_tbl_start_addr =
  505. IPA_MEM_PART(v4_flt_hash_ofst) + smem_restr_bytes;
  506. req.v6_hash_filter_tbl_start_addr_valid = true;
  507. req.v6_hash_filter_tbl_start_addr =
  508. IPA_MEM_PART(v6_flt_hash_ofst) + smem_restr_bytes;
  509. }
  510. req.hw_stats_quota_base_addr_valid = true;
  511. req.hw_stats_quota_base_addr =
  512. IPA_MEM_PART(stats_quota_ofst) + smem_restr_bytes;
  513. req.hw_stats_quota_size_valid = true;
  514. req.hw_stats_quota_size = IPA_MEM_PART(stats_quota_size);
  515. req.hw_drop_stats_base_addr_valid = true;
  516. req.hw_drop_stats_base_addr =
  517. IPA_MEM_PART(stats_drop_ofst) + smem_restr_bytes;
  518. req.hw_drop_stats_table_size_valid = true;
  519. req.hw_drop_stats_table_size = IPA_MEM_PART(stats_drop_size);
  520. if (!ipa3_uc_loaded_check()) { /* First time boot */
  521. req.is_ssr_bootup_valid = false;
  522. req.is_ssr_bootup = 0;
  523. } else { /* After SSR boot */
  524. req.is_ssr_bootup_valid = true;
  525. req.is_ssr_bootup = 1;
  526. }
  527. IPAWANDBG("platform_type %d\n", req.platform_type);
  528. IPAWANDBG("hdr_tbl_info.modem_offset_start %d\n",
  529. req.hdr_tbl_info.modem_offset_start);
  530. IPAWANDBG("hdr_tbl_info.modem_offset_end %d\n",
  531. req.hdr_tbl_info.modem_offset_end);
  532. IPAWANDBG("v4_route_tbl_info.route_tbl_start_addr %d\n",
  533. req.v4_route_tbl_info.route_tbl_start_addr);
  534. IPAWANDBG("v4_route_tbl_info.num_indices %d\n",
  535. req.v4_route_tbl_info.num_indices);
  536. IPAWANDBG("v6_route_tbl_info.route_tbl_start_addr %d\n",
  537. req.v6_route_tbl_info.route_tbl_start_addr);
  538. IPAWANDBG("v6_route_tbl_info.num_indices %d\n",
  539. req.v6_route_tbl_info.num_indices);
  540. IPAWANDBG("v4_filter_tbl_start_addr %d\n",
  541. req.v4_filter_tbl_start_addr);
  542. IPAWANDBG("v6_filter_tbl_start_addr %d\n",
  543. req.v6_filter_tbl_start_addr);
  544. IPAWANDBG("modem_mem_info.block_start_addr %d\n",
  545. req.modem_mem_info.block_start_addr);
  546. IPAWANDBG("modem_mem_info.size %d\n",
  547. req.modem_mem_info.size);
  548. IPAWANDBG("ctrl_comm_dest_end_pt %d\n",
  549. req.ctrl_comm_dest_end_pt);
  550. IPAWANDBG("is_ssr_bootup %d\n",
  551. req.is_ssr_bootup);
  552. IPAWANDBG("v4_hash_route_tbl_info.route_tbl_start_addr %d\n",
  553. req.v4_hash_route_tbl_info.route_tbl_start_addr);
  554. IPAWANDBG("v4_hash_route_tbl_info.num_indices %d\n",
  555. req.v4_hash_route_tbl_info.num_indices);
  556. IPAWANDBG("v6_hash_route_tbl_info.route_tbl_start_addr %d\n",
  557. req.v6_hash_route_tbl_info.route_tbl_start_addr);
  558. IPAWANDBG("v6_hash_route_tbl_info.num_indices %d\n",
  559. req.v6_hash_route_tbl_info.num_indices);
  560. IPAWANDBG("v4_hash_filter_tbl_start_addr %d\n",
  561. req.v4_hash_filter_tbl_start_addr);
  562. IPAWANDBG("v6_hash_filter_tbl_start_addr %d\n",
  563. req.v6_hash_filter_tbl_start_addr);
  564. req_desc.max_msg_len = QMI_IPA_INIT_MODEM_DRIVER_REQ_MAX_MSG_LEN_V01;
  565. req_desc.msg_id = QMI_IPA_INIT_MODEM_DRIVER_REQ_V01;
  566. req_desc.ei_array = ipa3_init_modem_driver_req_msg_data_v01_ei;
  567. resp_desc.max_msg_len = QMI_IPA_INIT_MODEM_DRIVER_RESP_MAX_MSG_LEN_V01;
  568. resp_desc.msg_id = QMI_IPA_INIT_MODEM_DRIVER_RESP_V01;
  569. resp_desc.ei_array = ipa3_init_modem_driver_resp_msg_data_v01_ei;
  570. pr_info("Sending QMI_IPA_INIT_MODEM_DRIVER_REQ_V01\n");
  571. if (unlikely(!ipa_q6_clnt))
  572. return -ETIMEDOUT;
  573. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  574. &req_desc, &req,
  575. &resp_desc, &resp,
  576. QMI_SEND_REQ_TIMEOUT_MS);
  577. if (rc < 0) {
  578. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  579. QMI_IPA_INIT_MODEM_DRIVER_REQ_V01,
  580. rc);
  581. return rc;
  582. }
  583. pr_info("QMI_IPA_INIT_MODEM_DRIVER_REQ_V01 response received\n");
  584. return ipa3_check_qmi_response(rc,
  585. QMI_IPA_INIT_MODEM_DRIVER_REQ_V01, resp.resp.result,
  586. resp.resp.error, "ipa_init_modem_driver_resp_msg_v01");
  587. }
  588. /* sending filter-install-request to modem*/
  589. int ipa3_qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req)
  590. {
  591. struct ipa_install_fltr_rule_resp_msg_v01 resp;
  592. struct ipa_msg_desc req_desc, resp_desc;
  593. int rc;
  594. int i;
  595. /* check if modem up */
  596. if (!ipa3_qmi_indication_fin ||
  597. !ipa3_qmi_modem_init_fin ||
  598. !ipa_q6_clnt) {
  599. IPAWANDBG("modem QMI haven't up yet\n");
  600. return -EINVAL;
  601. }
  602. /* check if the filter rules from IPACM is valid */
  603. if (req->filter_spec_list_len == 0) {
  604. IPAWANDBG("IPACM pass zero rules to Q6\n");
  605. } else {
  606. IPAWANDBG("IPACM pass %u rules to Q6\n",
  607. req->filter_spec_list_len);
  608. }
  609. if (req->filter_spec_list_len >= QMI_IPA_MAX_FILTERS_V01) {
  610. IPAWANDBG(
  611. "IPACM passes the number of filtering rules exceed limit\n");
  612. return -EINVAL;
  613. } else if (req->source_pipe_index_valid != 0) {
  614. IPAWANDBG(
  615. "IPACM passes source_pipe_index_valid not zero 0 != %d\n",
  616. req->source_pipe_index_valid);
  617. return -EINVAL;
  618. } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) {
  619. IPAWANDBG(
  620. "IPACM passes source pipe index not valid ID = %d\n",
  621. req->source_pipe_index);
  622. return -EINVAL;
  623. }
  624. for (i = 0; i < req->filter_spec_list_len; i++) {
  625. if ((req->filter_spec_list[i].ip_type !=
  626. QMI_IPA_IP_TYPE_V4_V01) &&
  627. (req->filter_spec_list[i].ip_type !=
  628. QMI_IPA_IP_TYPE_V6_V01))
  629. return -EINVAL;
  630. if (req->filter_spec_list[i].is_mux_id_valid == false)
  631. return -EINVAL;
  632. if (req->filter_spec_list[i].is_routing_table_index_valid
  633. == false)
  634. return -EINVAL;
  635. if ((req->filter_spec_list[i].filter_action <=
  636. QMI_IPA_FILTER_ACTION_INVALID_V01) ||
  637. (req->filter_spec_list[i].filter_action >
  638. QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
  639. return -EINVAL;
  640. }
  641. mutex_lock(&ipa3_qmi_lock);
  642. if (ipa3_qmi_ctx != NULL) {
  643. /* cache the qmi_filter_request */
  644. memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[
  645. ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg]),
  646. req,
  647. sizeof(struct ipa_install_fltr_rule_req_msg_v01));
  648. ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg++;
  649. ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10;
  650. }
  651. mutex_unlock(&ipa3_qmi_lock);
  652. req_desc.max_msg_len = QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01;
  653. req_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_REQ_V01;
  654. req_desc.ei_array = ipa3_install_fltr_rule_req_msg_data_v01_ei;
  655. memset(&resp, 0, sizeof(struct ipa_install_fltr_rule_resp_msg_v01));
  656. resp_desc.max_msg_len =
  657. QMI_IPA_INSTALL_FILTER_RULE_RESP_MAX_MSG_LEN_V01;
  658. resp_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_RESP_V01;
  659. resp_desc.ei_array = ipa3_install_fltr_rule_resp_msg_data_v01_ei;
  660. if (unlikely(!ipa_q6_clnt))
  661. return -ETIMEDOUT;
  662. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  663. &req_desc, req,
  664. &resp_desc, &resp,
  665. QMI_SEND_REQ_TIMEOUT_MS);
  666. if (rc < 0) {
  667. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  668. QMI_IPA_INSTALL_FILTER_RULE_REQ_V01,
  669. rc);
  670. return rc;
  671. }
  672. return ipa3_check_qmi_response(rc,
  673. QMI_IPA_INSTALL_FILTER_RULE_REQ_V01, resp.resp.result,
  674. resp.resp.error, "ipa_install_filter");
  675. }
  676. /* sending filter-install-request to modem*/
  677. int ipa3_qmi_filter_request_ex_send(
  678. struct ipa_install_fltr_rule_req_ex_msg_v01 *req)
  679. {
  680. struct ipa_install_fltr_rule_resp_ex_msg_v01 resp;
  681. struct ipa_msg_desc req_desc, resp_desc;
  682. int rc;
  683. int i;
  684. /* check if modem up */
  685. if (!ipa3_qmi_indication_fin ||
  686. !ipa3_qmi_modem_init_fin ||
  687. !ipa_q6_clnt) {
  688. IPAWANDBG("modem QMI haven't up yet\n");
  689. return -EINVAL;
  690. }
  691. /* check if the filter rules from IPACM is valid */
  692. if (req->filter_spec_ex_list_len == 0) {
  693. IPAWANDBG("IPACM pass zero rules to Q6\n");
  694. } else {
  695. IPAWANDBG("IPACM pass %u rules to Q6\n",
  696. req->filter_spec_ex_list_len);
  697. }
  698. if (req->filter_spec_ex_list_len >= QMI_IPA_MAX_FILTERS_EX_V01) {
  699. IPAWANDBG(
  700. "IPACM pass the number of filtering rules exceed limit\n");
  701. return -EINVAL;
  702. } else if (req->source_pipe_index_valid != 0) {
  703. IPAWANDBG(
  704. "IPACM passes source_pipe_index_valid not zero 0 != %d\n",
  705. req->source_pipe_index_valid);
  706. return -EINVAL;
  707. }
  708. for (i = 0; i < req->filter_spec_ex_list_len; i++) {
  709. if ((req->filter_spec_ex_list[i].ip_type !=
  710. QMI_IPA_IP_TYPE_V4_V01) &&
  711. (req->filter_spec_ex_list[i].ip_type !=
  712. QMI_IPA_IP_TYPE_V6_V01))
  713. return -EINVAL;
  714. if (req->filter_spec_ex_list[i].is_mux_id_valid == false)
  715. return -EINVAL;
  716. if (req->filter_spec_ex_list[i].is_routing_table_index_valid
  717. == false)
  718. return -EINVAL;
  719. if ((req->filter_spec_ex_list[i].filter_action <=
  720. QMI_IPA_FILTER_ACTION_INVALID_V01) ||
  721. (req->filter_spec_ex_list[i].filter_action >
  722. QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
  723. return -EINVAL;
  724. }
  725. mutex_lock(&ipa3_qmi_lock);
  726. if (ipa3_qmi_ctx != NULL) {
  727. /* cache the qmi_filter_request */
  728. memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_ex_msg_cache[
  729. ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg]),
  730. req,
  731. sizeof(struct ipa_install_fltr_rule_req_ex_msg_v01));
  732. ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg++;
  733. ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg %= 10;
  734. }
  735. mutex_unlock(&ipa3_qmi_lock);
  736. req_desc.max_msg_len =
  737. QMI_IPA_INSTALL_FILTER_RULE_EX_REQ_MAX_MSG_LEN_V01;
  738. req_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_EX_REQ_V01;
  739. req_desc.ei_array = ipa3_install_fltr_rule_req_ex_msg_data_v01_ei;
  740. memset(&resp, 0, sizeof(struct ipa_install_fltr_rule_resp_ex_msg_v01));
  741. resp_desc.max_msg_len =
  742. QMI_IPA_INSTALL_FILTER_RULE_EX_RESP_MAX_MSG_LEN_V01;
  743. resp_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_EX_RESP_V01;
  744. resp_desc.ei_array = ipa3_install_fltr_rule_resp_ex_msg_data_v01_ei;
  745. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  746. &req_desc, req,
  747. &resp_desc, &resp,
  748. QMI_SEND_REQ_TIMEOUT_MS);
  749. if (rc < 0) {
  750. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  751. QMI_IPA_INSTALL_FILTER_RULE_EX_REQ_V01,
  752. rc);
  753. return rc;
  754. }
  755. return ipa3_check_qmi_response(rc,
  756. QMI_IPA_INSTALL_FILTER_RULE_EX_REQ_V01, resp.resp.result,
  757. resp.resp.error, "ipa_install_filter");
  758. }
  759. /* sending add offload-connection-request to modem*/
  760. int ipa3_qmi_add_offload_request_send(
  761. struct ipa_add_offload_connection_req_msg_v01 *req)
  762. {
  763. struct ipa_add_offload_connection_resp_msg_v01 resp;
  764. struct ipa_msg_desc req_desc, resp_desc;
  765. int rc = 0;
  766. int i, j;
  767. uint32_t id;
  768. /* check if modem up */
  769. if (!ipa3_qmi_modem_init_fin ||
  770. !ipa_q6_clnt) {
  771. IPAWANDBG("modem QMI haven't up yet\n");
  772. return -EINVAL;
  773. }
  774. /* check if the filter rules from IPACM is valid */
  775. if (req->filter_spec_ex2_list_len == 0) {
  776. IPAWANDBG("IPACM pass zero rules to Q6\n");
  777. } else {
  778. IPAWANDBG("IPACM pass %u rules to Q6\n",
  779. req->filter_spec_ex2_list_len);
  780. }
  781. /* currently set total max to 64 */
  782. if (req->filter_spec_ex2_list_len +
  783. ipa3_qmi_ctx->num_ipa_offload_connection
  784. >= QMI_IPA_MAX_FILTERS_V01) {
  785. IPAWANDBG(
  786. "cur(%d), req(%d), exceed limit (%d)\n",
  787. ipa3_qmi_ctx->num_ipa_offload_connection,
  788. req->filter_spec_ex2_list_len,
  789. QMI_IPA_MAX_FILTERS_V01);
  790. return -EINVAL;
  791. }
  792. for (i = 0; i < req->filter_spec_ex2_list_len; i++) {
  793. if ((req->filter_spec_ex2_list[i].ip_type !=
  794. QMI_IPA_IP_TYPE_V4_V01) &&
  795. (req->filter_spec_ex2_list[i].ip_type !=
  796. QMI_IPA_IP_TYPE_V6_V01))
  797. return -EINVAL;
  798. if (req->filter_spec_ex2_list[i].is_mux_id_valid == false)
  799. return -EINVAL;
  800. if ((req->filter_spec_ex2_list[i].filter_action <=
  801. QMI_IPA_FILTER_ACTION_INVALID_V01) ||
  802. (req->filter_spec_ex2_list[i].filter_action >
  803. QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
  804. return -EINVAL;
  805. }
  806. req_desc.max_msg_len =
  807. IPA_ADD_OFFLOAD_CONNECTION_REQ_MSG_V01_MAX_MSG_LEN;
  808. req_desc.msg_id = QMI_IPA_ADD_OFFLOAD_CONNECTION_REQ_V01;
  809. req_desc.ei_array = ipa_add_offload_connection_req_msg_v01_ei;
  810. memset(&resp, 0, sizeof(struct
  811. ipa_add_offload_connection_resp_msg_v01));
  812. resp_desc.max_msg_len =
  813. IPA_ADD_OFFLOAD_CONNECTION_RESP_MSG_V01_MAX_MSG_LEN;
  814. resp_desc.msg_id = QMI_IPA_ADD_OFFLOAD_CONNECTION_RESP_V01;
  815. resp_desc.ei_array = ipa_add_offload_connection_resp_msg_v01_ei;
  816. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  817. &req_desc, req,
  818. &resp_desc, &resp,
  819. QMI_SEND_REQ_TIMEOUT_MS);
  820. if (rc < 0) {
  821. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  822. QMI_IPA_ADD_OFFLOAD_CONNECTION_REQ_V01,
  823. rc);
  824. return rc;
  825. }
  826. rc = ipa3_check_qmi_response(rc,
  827. QMI_IPA_ADD_OFFLOAD_CONNECTION_REQ_V01, resp.resp.result,
  828. resp.resp.error, "ipa_add_offload_connection");
  829. if (rc) {
  830. IPAWANERR("QMI get Response %d failed, rc= %d\n",
  831. QMI_IPA_ADD_OFFLOAD_CONNECTION_REQ_V01,
  832. rc);
  833. return rc;
  834. }
  835. /* Check & copy rule-handle */
  836. if (!resp.filter_handle_list_valid) {
  837. IPAWANERR("QMI resp invalid %d failed\n",
  838. resp.filter_handle_list_valid);
  839. return -ERANGE;
  840. }
  841. if (resp.filter_handle_list_len !=
  842. req->filter_spec_ex2_list_len) {
  843. IPAWANERR("QMI resp invalid size %d req %d\n",
  844. resp.filter_handle_list_len,
  845. req->filter_spec_ex2_list_len);
  846. return -ERANGE;
  847. }
  848. mutex_lock(&ipa3_qmi_lock);
  849. for (i = 0; i < req->filter_spec_ex2_list_len; i++) {
  850. id = resp.filter_handle_list[i].filter_spec_identifier;
  851. /* check rule-id matched or not */
  852. if (req->filter_spec_ex2_list[i].rule_id !=
  853. id) {
  854. IPAWANERR("QMI error (%d)st-(%d) rule-id (%d)\n",
  855. i,
  856. id,
  857. req->filter_spec_ex2_list[i].rule_id);
  858. mutex_unlock(&ipa3_qmi_lock);
  859. return -EINVAL;
  860. }
  861. /* find free spot*/
  862. for (j = 0; j < QMI_IPA_MAX_FILTERS_V01; j++) {
  863. if (!ipa3_qmi_ctx->ipa_offload_cache[j].valid)
  864. break;
  865. }
  866. if (j == QMI_IPA_MAX_FILTERS_V01) {
  867. IPAWANERR("can't find free spot for rule-id %d\n",
  868. id);
  869. mutex_unlock(&ipa3_qmi_lock);
  870. return -EINVAL;
  871. }
  872. /* save rule-id handle to cache */
  873. ipa3_qmi_ctx->ipa_offload_cache[j].rule_id =
  874. resp.filter_handle_list[i].filter_spec_identifier;
  875. ipa3_qmi_ctx->ipa_offload_cache[j].rule_hdl =
  876. resp.filter_handle_list[i].filter_handle;
  877. ipa3_qmi_ctx->ipa_offload_cache[j].valid = true;
  878. ipa3_qmi_ctx->ipa_offload_cache[j].ip_type =
  879. req->filter_spec_ex2_list[i].ip_type;
  880. ipa3_qmi_ctx->num_ipa_offload_connection++;
  881. }
  882. mutex_unlock(&ipa3_qmi_lock);
  883. IPAWANDBG("Update cached conntrack entries (%d)\n",
  884. ipa3_qmi_ctx->num_ipa_offload_connection);
  885. return rc;
  886. }
  887. /* sending rmv offload-connection-request to modem*/
  888. int ipa3_qmi_rmv_offload_request_send(
  889. struct ipa_remove_offload_connection_req_msg_v01 *req)
  890. {
  891. struct ipa_remove_offload_connection_resp_msg_v01 resp;
  892. struct ipa_msg_desc req_desc, resp_desc;
  893. int rc = 0;
  894. int i, j;
  895. uint32_t id;
  896. /* check if modem up */
  897. if (!ipa3_qmi_modem_init_fin ||
  898. !ipa_q6_clnt) {
  899. IPAWANDBG("modem QMI haven't up yet\n");
  900. return -EINVAL;
  901. }
  902. /* check if the # of handles from IPACM is valid */
  903. if (req->filter_handle_list_len == 0) {
  904. IPAWANDBG("IPACM deleted zero rules !\n");
  905. return -EINVAL;
  906. }
  907. IPAWANDBG("IPACM pass (%d) rules handles to Q6, cur (%d)\n",
  908. req->filter_handle_list_len,
  909. ipa3_qmi_ctx->num_ipa_offload_connection);
  910. /* max as num_ipa_offload_connection */
  911. if (req->filter_handle_list_len >=
  912. ipa3_qmi_ctx->num_ipa_offload_connection) {
  913. IPAWANDBG(
  914. "cur(%d), req_rmv(%d)\n",
  915. ipa3_qmi_ctx->num_ipa_offload_connection,
  916. req->filter_handle_list_len);
  917. return -EINVAL;
  918. }
  919. mutex_lock(&ipa3_qmi_lock);
  920. for (i = 0; i < req->filter_handle_list_len; i++) {
  921. /* check if rule-id match */
  922. id =
  923. req->filter_handle_list[i].filter_spec_identifier;
  924. for (j = 0; j < QMI_IPA_MAX_FILTERS_V01; j++) {
  925. if ((ipa3_qmi_ctx->ipa_offload_cache[j].valid) &&
  926. (ipa3_qmi_ctx->ipa_offload_cache[j].rule_id ==
  927. id))
  928. break;
  929. }
  930. if (j == QMI_IPA_MAX_FILTERS_V01) {
  931. IPAWANERR("can't find rule-id %d\n",
  932. id);
  933. mutex_unlock(&ipa3_qmi_lock);
  934. return -EINVAL;
  935. }
  936. /* fill up the filter_handle */
  937. req->filter_handle_list[i].filter_handle =
  938. ipa3_qmi_ctx->ipa_offload_cache[j].rule_hdl;
  939. ipa3_qmi_ctx->ipa_offload_cache[j].valid = false;
  940. ipa3_qmi_ctx->num_ipa_offload_connection--;
  941. }
  942. mutex_unlock(&ipa3_qmi_lock);
  943. req_desc.max_msg_len =
  944. IPA_REMOVE_OFFLOAD_CONNECTION_REQ_MSG_V01_MAX_MSG_LEN;
  945. req_desc.msg_id = QMI_IPA_REMOVE_OFFLOAD_CONNECTION_REQ_V01;
  946. req_desc.ei_array = ipa_remove_offload_connection_req_msg_v01_ei;
  947. memset(&resp, 0, sizeof(struct
  948. ipa_remove_offload_connection_resp_msg_v01));
  949. resp_desc.max_msg_len =
  950. IPA_REMOVE_OFFLOAD_CONNECTION_RESP_MSG_V01_MAX_MSG_LEN;
  951. resp_desc.msg_id = QMI_IPA_REMOVE_OFFLOAD_CONNECTION_RESP_V01;
  952. resp_desc.ei_array = ipa_remove_offload_connection_resp_msg_v01_ei;
  953. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  954. &req_desc, req,
  955. &resp_desc, &resp,
  956. QMI_SEND_REQ_TIMEOUT_MS);
  957. if (rc < 0) {
  958. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  959. QMI_IPA_REMOVE_OFFLOAD_CONNECTION_REQ_V01,
  960. rc);
  961. return rc;
  962. }
  963. IPAWANDBG("left cached conntrack entries (%d)\n",
  964. ipa3_qmi_ctx->num_ipa_offload_connection);
  965. return ipa3_check_qmi_response(rc,
  966. QMI_IPA_REMOVE_OFFLOAD_CONNECTION_REQ_V01, resp.resp.result,
  967. resp.resp.error, "ipa_rmv_offload_connection");
  968. }
  969. /* sending ul-filter-install-request to modem*/
  970. int ipa3_qmi_ul_filter_request_send(
  971. struct ipa_configure_ul_firewall_rules_req_msg_v01 *req)
  972. {
  973. struct ipa_configure_ul_firewall_rules_resp_msg_v01 resp;
  974. struct ipa_msg_desc req_desc, resp_desc;
  975. int rc, i;
  976. IPAWANDBG("IPACM pass %u rules to Q6\n",
  977. req->firewall_rules_list_len);
  978. mutex_lock(&ipa3_qmi_lock);
  979. if (ipa3_qmi_ctx != NULL) {
  980. /* cache the qmi_filter_request */
  981. memcpy(
  982. &(ipa3_qmi_ctx->ipa_configure_ul_firewall_rules_req_msg_cache[
  983. ipa3_qmi_ctx->num_ipa_configure_ul_firewall_rules_req_msg]),
  984. req,
  985. sizeof(struct
  986. ipa_configure_ul_firewall_rules_req_msg_v01));
  987. ipa3_qmi_ctx->num_ipa_configure_ul_firewall_rules_req_msg++;
  988. ipa3_qmi_ctx->num_ipa_configure_ul_firewall_rules_req_msg %=
  989. MAX_NUM_QMI_RULE_CACHE;
  990. }
  991. mutex_unlock(&ipa3_qmi_lock);
  992. /* check if modem is up */
  993. if (!ipa3_qmi_indication_fin ||
  994. !ipa3_qmi_modem_init_fin ||
  995. !ipa_q6_clnt) {
  996. IPAWANDBG("modem QMI service is not up yet\n");
  997. return -EINVAL;
  998. }
  999. /* Passing 0 rules means that firewall is disabled */
  1000. if (req->firewall_rules_list_len == 0)
  1001. IPAWANDBG("IPACM passed 0 rules to Q6\n");
  1002. if (req->firewall_rules_list_len >= QMI_IPA_MAX_UL_FIREWALL_RULES_V01) {
  1003. IPAWANERR(
  1004. "Number of rules passed by IPACM, %d, exceed limit %d\n",
  1005. req->firewall_rules_list_len,
  1006. QMI_IPA_MAX_UL_FIREWALL_RULES_V01);
  1007. return -EINVAL;
  1008. }
  1009. /* Check for valid IP type */
  1010. for (i = 0; i < req->firewall_rules_list_len; i++) {
  1011. if (req->firewall_rules_list[i].ip_type !=
  1012. QMI_IPA_IP_TYPE_V4_V01 &&
  1013. req->firewall_rules_list[i].ip_type !=
  1014. QMI_IPA_IP_TYPE_V6_V01) {
  1015. IPAWANERR("Invalid IP type %d\n",
  1016. req->firewall_rules_list[i].ip_type);
  1017. return -EINVAL;
  1018. }
  1019. }
  1020. req_desc.max_msg_len =
  1021. QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_MAX_MSG_LEN_V01;
  1022. req_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01;
  1023. req_desc.ei_array =
  1024. ipa3_configure_ul_firewall_rules_req_msg_data_v01_ei;
  1025. memset(&resp, 0,
  1026. sizeof(struct ipa_configure_ul_firewall_rules_resp_msg_v01));
  1027. resp_desc.max_msg_len =
  1028. QMI_IPA_INSTALL_UL_FIREWALL_RULES_RESP_MAX_MSG_LEN_V01;
  1029. resp_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_RESP_V01;
  1030. resp_desc.ei_array =
  1031. ipa3_configure_ul_firewall_rules_resp_msg_data_v01_ei;
  1032. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1033. &req_desc, req,
  1034. &resp_desc, &resp,
  1035. QMI_SEND_REQ_TIMEOUT_MS);
  1036. if (rc < 0) {
  1037. IPAWANERR("send Req %d failed, rc= %d\n",
  1038. QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01,
  1039. rc);
  1040. return rc;
  1041. }
  1042. return ipa3_check_qmi_response(rc,
  1043. QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01,
  1044. resp.resp.result,
  1045. resp.resp.error, "ipa_received_ul_firewall_filter");
  1046. }
  1047. int ipa3_qmi_enable_force_clear_datapath_send(
  1048. struct ipa_enable_force_clear_datapath_req_msg_v01 *req)
  1049. {
  1050. struct ipa_enable_force_clear_datapath_resp_msg_v01 resp;
  1051. struct ipa_msg_desc req_desc, resp_desc;
  1052. int rc = 0;
  1053. if (!req || !req->source_pipe_bitmask) {
  1054. IPAWANERR("invalid params\n");
  1055. return -EINVAL;
  1056. }
  1057. if (ipa3_ctx->ipa3_hw_mode == IPA_HW_MODE_VIRTUAL ||
  1058. ipa3_ctx->ipa3_hw_mode == IPA_HW_MODE_EMULATION) {
  1059. IPAWANDBG("Simulating success on emu/virt mode\n");
  1060. return 0;
  1061. }
  1062. req_desc.max_msg_len =
  1063. QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_REQ_MAX_MSG_LEN_V01;
  1064. req_desc.msg_id = QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_REQ_V01;
  1065. req_desc.ei_array =
  1066. ipa3_enable_force_clear_datapath_req_msg_data_v01_ei;
  1067. memset(&resp, 0, sizeof(struct ipa_fltr_installed_notif_resp_msg_v01));
  1068. resp_desc.max_msg_len =
  1069. QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_RESP_MAX_MSG_LEN_V01;
  1070. resp_desc.msg_id = QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_RESP_V01;
  1071. resp_desc.ei_array =
  1072. ipa3_enable_force_clear_datapath_resp_msg_data_v01_ei;
  1073. if (unlikely(!ipa_q6_clnt))
  1074. return -ETIMEDOUT;
  1075. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1076. &req_desc, req,
  1077. &resp_desc, &resp,
  1078. QMI_IPA_FORCE_CLEAR_DATAPATH_TIMEOUT_MS);
  1079. if (rc < 0) {
  1080. IPAWANERR("send Req %d failed, rc= %d\n",
  1081. QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_REQ_V01,
  1082. rc);
  1083. return rc;
  1084. }
  1085. if (resp.resp.result != IPA_QMI_RESULT_SUCCESS_V01) {
  1086. IPAWANERR("filter_notify failed %d\n",
  1087. resp.resp.result);
  1088. return resp.resp.result;
  1089. }
  1090. return ipa3_check_qmi_response(rc,
  1091. QMI_IPA_ENABLE_FORCE_CLEAR_DATAPATH_REQ_V01,
  1092. resp.resp.result,
  1093. resp.resp.error, "ipa_enable_force_clear_datapath");
  1094. }
  1095. int ipa3_qmi_disable_force_clear_datapath_send(
  1096. struct ipa_disable_force_clear_datapath_req_msg_v01 *req)
  1097. {
  1098. struct ipa_disable_force_clear_datapath_resp_msg_v01 resp;
  1099. struct ipa_msg_desc req_desc, resp_desc;
  1100. int rc = 0;
  1101. if (!req) {
  1102. IPAWANERR("invalid params\n");
  1103. return -EINVAL;
  1104. }
  1105. if (ipa3_ctx->ipa3_hw_mode == IPA_HW_MODE_VIRTUAL ||
  1106. ipa3_ctx->ipa3_hw_mode == IPA_HW_MODE_EMULATION) {
  1107. IPAWANDBG("Simulating success on emu/virt mode\n");
  1108. return 0;
  1109. }
  1110. req_desc.max_msg_len =
  1111. QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_REQ_MAX_MSG_LEN_V01;
  1112. req_desc.msg_id = QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_REQ_V01;
  1113. req_desc.ei_array =
  1114. ipa3_disable_force_clear_datapath_req_msg_data_v01_ei;
  1115. memset(&resp, 0, sizeof(struct ipa_fltr_installed_notif_resp_msg_v01));
  1116. resp_desc.max_msg_len =
  1117. QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_RESP_MAX_MSG_LEN_V01;
  1118. resp_desc.msg_id = QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_RESP_V01;
  1119. resp_desc.ei_array =
  1120. ipa3_disable_force_clear_datapath_resp_msg_data_v01_ei;
  1121. if (unlikely(!ipa_q6_clnt))
  1122. return -ETIMEDOUT;
  1123. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1124. &req_desc, req,
  1125. &resp_desc, &resp,
  1126. QMI_IPA_FORCE_CLEAR_DATAPATH_TIMEOUT_MS);
  1127. if (rc < 0) {
  1128. IPAWANERR("send Req %d failed, rc= %d\n",
  1129. QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_REQ_V01,
  1130. rc);
  1131. return rc;
  1132. }
  1133. if (resp.resp.result != IPA_QMI_RESULT_SUCCESS_V01) {
  1134. IPAWANERR("filter_notify failed %d\n",
  1135. resp.resp.result);
  1136. return resp.resp.result;
  1137. }
  1138. return ipa3_check_qmi_response(rc,
  1139. QMI_IPA_DISABLE_FORCE_CLEAR_DATAPATH_REQ_V01,
  1140. resp.resp.result,
  1141. resp.resp.error, "ipa_disable_force_clear_datapath");
  1142. }
  1143. /* sending filter-installed-notify-request to modem*/
  1144. int ipa3_qmi_filter_notify_send(
  1145. struct ipa_fltr_installed_notif_req_msg_v01 *req)
  1146. {
  1147. struct ipa_fltr_installed_notif_resp_msg_v01 resp;
  1148. struct ipa_msg_desc req_desc, resp_desc;
  1149. int rc = 0;
  1150. /* check if the filter rules from IPACM is valid */
  1151. if (req->rule_id_len == 0) {
  1152. IPAWANDBG(" delete UL filter rule for pipe %d\n",
  1153. req->source_pipe_index);
  1154. } else if (req->rule_id_len > QMI_IPA_MAX_FILTERS_V01) {
  1155. IPAWANERR(" UL filter rule for pipe %d exceed max (%u)\n",
  1156. req->source_pipe_index,
  1157. req->rule_id_len);
  1158. return -EINVAL;
  1159. }
  1160. if (req->rule_id_ex_len == 0) {
  1161. IPAWANDBG(" delete UL filter rule for pipe %d\n",
  1162. req->source_pipe_index);
  1163. } else if (req->rule_id_ex_len > QMI_IPA_MAX_FILTERS_EX2_V01) {
  1164. IPAWANERR(" UL filter rule for pipe %d exceed max (%u)\n",
  1165. req->source_pipe_index,
  1166. req->rule_id_ex_len);
  1167. return -EINVAL;
  1168. }
  1169. if (req->install_status != IPA_QMI_RESULT_SUCCESS_V01) {
  1170. IPAWANERR(" UL filter rule for pipe %d install_status = %d\n",
  1171. req->source_pipe_index, req->install_status);
  1172. return -EINVAL;
  1173. } else if ((req->rule_id_valid != 1) &&
  1174. (req->rule_id_ex_valid != 1)) {
  1175. IPAWANERR(" UL filter rule for pipe %d rule_id_valid = %d/%d\n",
  1176. req->source_pipe_index, req->rule_id_valid,
  1177. req->rule_id_ex_valid);
  1178. return -EINVAL;
  1179. } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) {
  1180. IPAWANDBG(
  1181. "IPACM passes source pipe index not valid ID = %d\n",
  1182. req->source_pipe_index);
  1183. return -EINVAL;
  1184. } else if (((req->embedded_pipe_index_valid != true) ||
  1185. (req->embedded_call_mux_id_valid != true)) &&
  1186. ((req->embedded_pipe_index_valid != false) ||
  1187. (req->embedded_call_mux_id_valid != false))) {
  1188. IPAWANERR(
  1189. "IPACM passes embedded pipe and mux valid not valid\n");
  1190. return -EINVAL;
  1191. } else if (req->embedded_pipe_index >= ipa3_ctx->ipa_num_pipes) {
  1192. IPAWANERR("IPACM passes source pipe index not valid ID = %d\n",
  1193. req->source_pipe_index);
  1194. return -EINVAL;
  1195. }
  1196. if (req->source_pipe_index == -1) {
  1197. IPAWANERR("Source pipe index invalid\n");
  1198. return -EINVAL;
  1199. }
  1200. mutex_lock(&ipa3_qmi_lock);
  1201. if (ipa3_qmi_ctx != NULL) {
  1202. /* cache the qmi_filter_request */
  1203. memcpy(&(ipa3_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[
  1204. ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]),
  1205. req,
  1206. sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
  1207. ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++;
  1208. ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10;
  1209. }
  1210. mutex_unlock(&ipa3_qmi_lock);
  1211. req_desc.max_msg_len =
  1212. QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01;
  1213. req_desc.msg_id = QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_V01;
  1214. req_desc.ei_array = ipa3_fltr_installed_notif_req_msg_data_v01_ei;
  1215. memset(&resp, 0, sizeof(struct ipa_fltr_installed_notif_resp_msg_v01));
  1216. resp_desc.max_msg_len =
  1217. QMI_IPA_FILTER_INSTALLED_NOTIF_RESP_MAX_MSG_LEN_V01;
  1218. resp_desc.msg_id = QMI_IPA_FILTER_INSTALLED_NOTIF_RESP_V01;
  1219. resp_desc.ei_array = ipa3_fltr_installed_notif_resp_msg_data_v01_ei;
  1220. if (unlikely(!ipa_q6_clnt))
  1221. return -ETIMEDOUT;
  1222. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1223. &req_desc, req,
  1224. &resp_desc, &resp,
  1225. QMI_SEND_REQ_TIMEOUT_MS);
  1226. if (rc < 0) {
  1227. IPAWANERR("send Req %d failed, rc= %d\n",
  1228. QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_V01,
  1229. rc);
  1230. return rc;
  1231. }
  1232. return ipa3_check_qmi_response(rc,
  1233. QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_V01, resp.resp.result,
  1234. resp.resp.error, "ipa_fltr_installed_notif_resp");
  1235. }
  1236. static void ipa3_q6_clnt_quota_reached_ind_cb(struct qmi_handle *handle,
  1237. struct sockaddr_qrtr *sq,
  1238. struct qmi_txn *txn,
  1239. const void *data)
  1240. {
  1241. struct ipa_data_usage_quota_reached_ind_msg_v01 *qmi_ind;
  1242. if (handle != ipa_q6_clnt) {
  1243. IPAWANERR("Wrong client\n");
  1244. return;
  1245. }
  1246. qmi_ind = (struct ipa_data_usage_quota_reached_ind_msg_v01 *) data;
  1247. IPAWANDBG("Quota reached indication on qmux(%d) Mbytes(%lu)\n",
  1248. qmi_ind->apn.mux_id, (unsigned long) qmi_ind->apn.num_Mbytes);
  1249. ipa3_broadcast_quota_reach_ind(qmi_ind->apn.mux_id,
  1250. IPA_UPSTEAM_MODEM);
  1251. }
  1252. static void ipa3_q6_clnt_install_firewall_rules_ind_cb(
  1253. struct qmi_handle *handle,
  1254. struct sockaddr_qrtr *sq,
  1255. struct qmi_txn *txn,
  1256. const void *data)
  1257. {
  1258. struct ipa_configure_ul_firewall_rules_ind_msg_v01 qmi_ul_firewall_ind;
  1259. memset(&qmi_ul_firewall_ind, 0, sizeof(
  1260. struct ipa_configure_ul_firewall_rules_ind_msg_v01));
  1261. memcpy(&qmi_ul_firewall_ind, data, sizeof(
  1262. struct ipa_configure_ul_firewall_rules_ind_msg_v01));
  1263. IPAWANDBG("UL firewall rules install indication on Q6");
  1264. if (qmi_ul_firewall_ind.result.is_success ==
  1265. QMI_IPA_UL_FIREWALL_STATUS_SUCCESS_V01) {
  1266. IPAWANDBG(" : Success\n");
  1267. IPAWANDBG
  1268. ("Mux ID : %d\n", qmi_ul_firewall_ind.result.mux_id);
  1269. } else if (qmi_ul_firewall_ind.result.is_success ==
  1270. QMI_IPA_UL_FIREWALL_STATUS_FAILURE_V01) {
  1271. IPAWANERR(": Failure\n");
  1272. } else {
  1273. IPAWANERR(": Unexpected Result");
  1274. }
  1275. }
  1276. static void ipa3_q6_clnt_svc_arrive(struct work_struct *work)
  1277. {
  1278. int rc;
  1279. struct ipa_master_driver_init_complt_ind_msg_v01 ind;
  1280. rc = kernel_connect(ipa_q6_clnt->sock,
  1281. (struct sockaddr *) &ipa3_qmi_ctx->server_sq,
  1282. sizeof(ipa3_qmi_ctx->server_sq),
  1283. 0);
  1284. if (rc < 0) {
  1285. IPAWANERR("Couldnt connect Server\n");
  1286. return;
  1287. }
  1288. if (!send_qmi_init_q6)
  1289. return;
  1290. IPAWANDBG("Q6 QMI service available now\n");
  1291. if (ipa3_is_apq()) {
  1292. ipa3_qmi_modem_init_fin = true;
  1293. IPAWANDBG("QMI-client complete, ipa3_qmi_modem_init_fin : %d\n",
  1294. ipa3_qmi_modem_init_fin);
  1295. return;
  1296. }
  1297. /* Initialize modem IPA-driver */
  1298. IPAWANDBG("send ipa3_qmi_init_modem_send_sync_msg to modem\n");
  1299. rc = ipa3_qmi_init_modem_send_sync_msg();
  1300. if ((rc == -ENETRESET) || (rc == -ENODEV)) {
  1301. IPAWANERR(
  1302. "ipa3_qmi_init_modem_send_sync_msg failed due to SSR!\n");
  1303. /* Cleanup when ipa3_wwan_remove is called */
  1304. vfree(ipa_q6_clnt);
  1305. ipa_q6_clnt = NULL;
  1306. return;
  1307. }
  1308. if (rc != 0) {
  1309. IPAWANERR("ipa3_qmi_init_modem_send_sync_msg failed\n");
  1310. /*
  1311. * Hardware not responding.
  1312. * This is a very unexpected scenario
  1313. * which requires a kernel panic in
  1314. * order to force dumps for QMI/Q6 side analysis.
  1315. */
  1316. BUG();
  1317. }
  1318. ipa3_qmi_modem_init_fin = true;
  1319. /* In cold-bootup, first_time_handshake = false */
  1320. ipa3_q6_handshake_complete(first_time_handshake);
  1321. first_time_handshake = true;
  1322. IPAWANDBG("complete, ipa3_qmi_modem_init_fin : %d\n",
  1323. ipa3_qmi_modem_init_fin);
  1324. if (ipa3_qmi_indication_fin) {
  1325. IPAWANDBG("send indication to modem (%d)\n",
  1326. ipa3_qmi_indication_fin);
  1327. memset(&ind, 0, sizeof(struct
  1328. ipa_master_driver_init_complt_ind_msg_v01));
  1329. ind.master_driver_init_status.result =
  1330. IPA_QMI_RESULT_SUCCESS_V01;
  1331. rc = qmi_send_indication(ipa3_svc_handle,
  1332. &ipa3_qmi_ctx->client_sq,
  1333. QMI_IPA_MASTER_DRIVER_INIT_COMPLETE_IND_V01,
  1334. QMI_IPA_MASTER_DRIVER_INIT_COMPLETE_IND_MAX_MSG_LEN_V01,
  1335. ipa3_master_driver_init_complt_ind_msg_data_v01_ei,
  1336. &ind);
  1337. IPAWANDBG("ipa_qmi_service_client good\n");
  1338. } else {
  1339. IPAWANERR("not send indication (%d)\n",
  1340. ipa3_qmi_indication_fin);
  1341. }
  1342. send_qmi_init_q6 = false;
  1343. }
  1344. static void ipa3_q6_clnt_svc_exit(struct work_struct *work)
  1345. {
  1346. if (ipa3_qmi_ctx != NULL) {
  1347. ipa3_qmi_ctx->server_sq.sq_family = 0;
  1348. ipa3_qmi_ctx->server_sq.sq_node = 0;
  1349. ipa3_qmi_ctx->server_sq.sq_port = 0;
  1350. }
  1351. }
  1352. static int ipa3_q6_clnt_svc_event_notify_svc_new(struct qmi_handle *qmi,
  1353. struct qmi_service *service)
  1354. {
  1355. IPAWANDBG("QMI svc:%d vers:%d ins:%d node:%d port:%d\n",
  1356. service->service, service->version, service->instance,
  1357. service->node, service->port);
  1358. if (ipa3_qmi_ctx != NULL) {
  1359. ipa3_qmi_ctx->server_sq.sq_family = AF_QIPCRTR;
  1360. ipa3_qmi_ctx->server_sq.sq_node = service->node;
  1361. ipa3_qmi_ctx->server_sq.sq_port = service->port;
  1362. }
  1363. if (!workqueues_stopped) {
  1364. queue_delayed_work(ipa_clnt_req_workqueue,
  1365. &ipa3_work_svc_arrive, 0);
  1366. }
  1367. return 0;
  1368. }
  1369. static void ipa3_q6_clnt_svc_event_notify_net_reset(struct qmi_handle *qmi)
  1370. {
  1371. if (!workqueues_stopped)
  1372. queue_delayed_work(ipa_clnt_req_workqueue,
  1373. &ipa3_work_svc_exit, 0);
  1374. }
  1375. static void ipa3_q6_clnt_svc_event_notify_svc_exit(struct qmi_handle *qmi,
  1376. struct qmi_service *svc)
  1377. {
  1378. IPAWANDBG("QMI svc:%d vers:%d ins:%d node:%d port:%d\n", svc->service,
  1379. svc->version, svc->instance, svc->node, svc->port);
  1380. if (!workqueues_stopped)
  1381. queue_delayed_work(ipa_clnt_req_workqueue,
  1382. &ipa3_work_svc_exit, 0);
  1383. }
  1384. static struct qmi_ops server_ops = {
  1385. .del_client = ipa3_a5_svc_disconnect_cb,
  1386. };
  1387. static struct qmi_ops client_ops = {
  1388. .new_server = ipa3_q6_clnt_svc_event_notify_svc_new,
  1389. .del_server = ipa3_q6_clnt_svc_event_notify_svc_exit,
  1390. .net_reset = ipa3_q6_clnt_svc_event_notify_net_reset,
  1391. };
  1392. static struct qmi_msg_handler server_handlers[] = {
  1393. {
  1394. .type = QMI_REQUEST,
  1395. .msg_id = QMI_IPA_INDICATION_REGISTER_REQ_V01,
  1396. .ei = ipa3_indication_reg_req_msg_data_v01_ei,
  1397. .decoded_size =
  1398. QMI_IPA_INDICATION_REGISTER_REQ_MAX_MSG_LEN_V01,
  1399. .fn = ipa3_handle_indication_req,
  1400. },
  1401. {
  1402. .type = QMI_REQUEST,
  1403. .msg_id = QMI_IPA_INSTALL_FILTER_RULE_REQ_V01,
  1404. .ei = ipa3_install_fltr_rule_req_msg_data_v01_ei,
  1405. .decoded_size =
  1406. QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01,
  1407. .fn = ipa3_handle_install_filter_rule_req,
  1408. },
  1409. {
  1410. .type = QMI_REQUEST,
  1411. .msg_id = QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_V01,
  1412. .ei = ipa3_fltr_installed_notif_req_msg_data_v01_ei,
  1413. .decoded_size =
  1414. QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01,
  1415. .fn = ipa3_handle_filter_installed_notify_req,
  1416. },
  1417. {
  1418. .type = QMI_REQUEST,
  1419. .msg_id = QMI_IPA_CONFIG_REQ_V01,
  1420. .ei = ipa3_config_req_msg_data_v01_ei,
  1421. .decoded_size = QMI_IPA_CONFIG_REQ_MAX_MSG_LEN_V01,
  1422. .fn = handle_ipa_config_req,
  1423. },
  1424. {
  1425. .type = QMI_REQUEST,
  1426. .msg_id = QMI_IPA_INIT_MODEM_DRIVER_CMPLT_REQ_V01,
  1427. .ei = ipa3_init_modem_driver_cmplt_req_msg_data_v01_ei,
  1428. .decoded_size =
  1429. QMI_IPA_INIT_MODEM_DRIVER_CMPLT_REQ_MAX_MSG_LEN_V01,
  1430. .fn = ipa3_handle_modem_init_cmplt_req,
  1431. },
  1432. {
  1433. .type = QMI_REQUEST,
  1434. .msg_id = QMI_IPA_INIT_MODEM_DRIVER_CMPLT_REQ_V01,
  1435. .ei = ipa3_init_modem_driver_cmplt_req_msg_data_v01_ei,
  1436. .decoded_size =
  1437. QMI_IPA_INIT_MODEM_DRIVER_CMPLT_REQ_MAX_MSG_LEN_V01,
  1438. .fn = ipa3_handle_modem_init_cmplt_req,
  1439. },
  1440. {
  1441. .type = QMI_REQUEST,
  1442. .msg_id = QMI_IPA_MHI_ALLOC_CHANNEL_REQ_V01,
  1443. .ei = ipa_mhi_alloc_channel_req_msg_v01_ei,
  1444. .decoded_size =
  1445. IPA_MHI_ALLOC_CHANNEL_REQ_MSG_V01_MAX_MSG_LEN,
  1446. .fn = ipa3_handle_mhi_alloc_channel_req,
  1447. },
  1448. {
  1449. .type = QMI_REQUEST,
  1450. .msg_id = QMI_IPA_MHI_CLK_VOTE_REQ_V01,
  1451. .ei = ipa_mhi_clk_vote_req_msg_v01_ei,
  1452. .decoded_size =
  1453. IPA_MHI_CLK_VOTE_REQ_MSG_V01_MAX_MSG_LEN,
  1454. .fn = ipa3_handle_mhi_vote_req,
  1455. },
  1456. };
  1457. /* clinet_handlers are client callbacks that will be called from QMI context
  1458. * when an indication from Q6 server arrives.
  1459. * In our case, client_handlers needs handling only for QMI_INDICATION,
  1460. * since the QMI_REQUEST/ QMI_RESPONSE are handled in a blocking fashion
  1461. * at the time of sending QMI_REQUESTs.
  1462. */
  1463. static struct qmi_msg_handler client_handlers[] = {
  1464. {
  1465. .type = QMI_INDICATION,
  1466. .msg_id = QMI_IPA_DATA_USAGE_QUOTA_REACHED_IND_V01,
  1467. .ei = ipa3_data_usage_quota_reached_ind_msg_data_v01_ei,
  1468. .decoded_size =
  1469. QMI_IPA_DATA_USAGE_QUOTA_REACHED_IND_MAX_MSG_LEN_V01,
  1470. .fn = ipa3_q6_clnt_quota_reached_ind_cb,
  1471. },
  1472. {
  1473. .type = QMI_INDICATION,
  1474. .msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_IND_V01,
  1475. .ei = ipa3_install_fltr_rule_req_msg_data_v01_ei,
  1476. .decoded_size =
  1477. QMI_IPA_INSTALL_UL_FIREWALL_RULES_IND_MAX_MSG_LEN_V01,
  1478. .fn = ipa3_q6_clnt_install_firewall_rules_ind_cb,
  1479. },
  1480. };
  1481. static void ipa3_qmi_service_init_worker(struct work_struct *work)
  1482. {
  1483. int rc;
  1484. /* start the QMI msg cache */
  1485. ipa3_qmi_ctx = vzalloc(sizeof(*ipa3_qmi_ctx));
  1486. if (!ipa3_qmi_ctx) {
  1487. IPAWANERR("Failed to allocate ipa3_qmi_ctx\n");
  1488. return;
  1489. }
  1490. if (ipa3_is_apq()) {
  1491. /* Only start QMI-client */
  1492. IPAWANDBG("Only start IPA A7 QMI client\n");
  1493. goto qmi_client_start;
  1494. }
  1495. /* Initialize QMI-service*/
  1496. IPAWANDBG("IPA A7 QMI init OK :>>>>\n");
  1497. ipa3_qmi_ctx->modem_cfg_emb_pipe_flt =
  1498. ipa3_get_modem_cfg_emb_pipe_flt();
  1499. ipa3_qmi_ctx->num_ipa_offload_connection = 0;
  1500. ipa3_svc_handle = vzalloc(sizeof(*ipa3_svc_handle));
  1501. if (!ipa3_svc_handle)
  1502. goto destroy_ipa_A7_svc_wq;
  1503. rc = qmi_handle_init(ipa3_svc_handle,
  1504. QMI_IPA_MAX_MSG_LEN,
  1505. &server_ops,
  1506. server_handlers);
  1507. if (rc < 0) {
  1508. IPAWANERR("Initializing ipa_a5 svc failed %d\n", rc);
  1509. goto destroy_qmi_handle;
  1510. }
  1511. rc = qmi_add_server(ipa3_svc_handle,
  1512. IPA_A5_SERVICE_SVC_ID,
  1513. IPA_A5_SVC_VERS,
  1514. IPA_A5_SERVICE_INS_ID);
  1515. if (rc < 0) {
  1516. IPAWANERR("Registering ipa_a5 svc failed %d\n",
  1517. rc);
  1518. goto deregister_qmi_srv;
  1519. }
  1520. qmi_client_start:
  1521. /* Initialize QMI-client */
  1522. ipa_clnt_req_workqueue = create_singlethread_workqueue("clnt_req");
  1523. if (!ipa_clnt_req_workqueue) {
  1524. IPAWANERR("Creating clnt_req workqueue failed\n");
  1525. goto deregister_qmi_srv;
  1526. }
  1527. /* Create a Local client port for QMI communication */
  1528. ipa_q6_clnt = vzalloc(sizeof(*ipa_q6_clnt));
  1529. if (!ipa_q6_clnt)
  1530. goto destroy_clnt_req_wq;
  1531. rc = qmi_handle_init(ipa_q6_clnt,
  1532. QMI_IPA_MAX_MSG_LEN,
  1533. &client_ops,
  1534. client_handlers);
  1535. if (rc < 0) {
  1536. IPAWANERR("Creating clnt handle failed\n");
  1537. goto destroy_qmi_client_handle;
  1538. }
  1539. rc = qmi_add_lookup(ipa_q6_clnt,
  1540. IPA_Q6_SERVICE_SVC_ID,
  1541. IPA_Q6_SVC_VERS,
  1542. IPA_Q6_SERVICE_INS_ID);
  1543. if (rc < 0) {
  1544. IPAWANERR("Adding Q6 Svc failed\n");
  1545. goto deregister_qmi_client;
  1546. }
  1547. /* get Q6 service and start send modem-initial to Q6 */
  1548. IPAWANDBG("wait service available\n");
  1549. return;
  1550. deregister_qmi_client:
  1551. qmi_handle_release(ipa_q6_clnt);
  1552. destroy_qmi_client_handle:
  1553. vfree(ipa_q6_clnt);
  1554. ipa_q6_clnt = NULL;
  1555. destroy_clnt_req_wq:
  1556. destroy_workqueue(ipa_clnt_req_workqueue);
  1557. ipa_clnt_req_workqueue = NULL;
  1558. deregister_qmi_srv:
  1559. if (!ipa3_is_apq())
  1560. qmi_handle_release(ipa3_svc_handle);
  1561. destroy_qmi_handle:
  1562. vfree(ipa3_qmi_ctx);
  1563. destroy_ipa_A7_svc_wq:
  1564. if (!ipa3_is_apq()) {
  1565. vfree(ipa3_svc_handle);
  1566. ipa3_svc_handle = NULL;
  1567. }
  1568. ipa3_qmi_ctx = NULL;
  1569. }
  1570. int ipa3_qmi_service_init(uint32_t wan_platform_type)
  1571. {
  1572. ipa_wan_platform = wan_platform_type;
  1573. ipa3_qmi_modem_init_fin = false;
  1574. ipa3_qmi_indication_fin = false;
  1575. ipa3_modem_init_cmplt = false;
  1576. send_qmi_init_q6 = true;
  1577. workqueues_stopped = false;
  1578. if (!ipa3_svc_handle) {
  1579. INIT_WORK(&ipa3_qmi_service_init_work,
  1580. ipa3_qmi_service_init_worker);
  1581. schedule_work(&ipa3_qmi_service_init_work);
  1582. }
  1583. return 0;
  1584. }
  1585. void ipa3_qmi_service_exit(void)
  1586. {
  1587. workqueues_stopped = true;
  1588. /* qmi-service */
  1589. if (ipa3_svc_handle != NULL) {
  1590. qmi_handle_release(ipa3_svc_handle);
  1591. vfree(ipa3_svc_handle);
  1592. ipa3_svc_handle = NULL;
  1593. }
  1594. /* qmi-client */
  1595. /* Release client handle */
  1596. if (ipa_q6_clnt != NULL) {
  1597. qmi_handle_release(ipa_q6_clnt);
  1598. vfree(ipa_q6_clnt);
  1599. ipa_q6_clnt = NULL;
  1600. if (ipa_clnt_req_workqueue) {
  1601. destroy_workqueue(ipa_clnt_req_workqueue);
  1602. ipa_clnt_req_workqueue = NULL;
  1603. }
  1604. }
  1605. /* clean the QMI msg cache */
  1606. mutex_lock(&ipa3_qmi_lock);
  1607. if (ipa3_qmi_ctx != NULL) {
  1608. vfree(ipa3_qmi_ctx);
  1609. ipa3_qmi_ctx = NULL;
  1610. }
  1611. mutex_unlock(&ipa3_qmi_lock);
  1612. ipa3_qmi_modem_init_fin = false;
  1613. ipa3_qmi_indication_fin = false;
  1614. ipa3_modem_init_cmplt = false;
  1615. send_qmi_init_q6 = true;
  1616. }
  1617. void ipa3_qmi_stop_workqueues(void)
  1618. {
  1619. IPAWANDBG("Stopping all QMI workqueues\n");
  1620. /* Stopping all workqueues so new work won't be scheduled */
  1621. workqueues_stopped = true;
  1622. /* Making sure that the current scheduled work won't be executed */
  1623. cancel_delayed_work(&ipa3_work_svc_arrive);
  1624. cancel_delayed_work(&ipa3_work_svc_exit);
  1625. }
  1626. /* voting for bus BW to ipa_rm*/
  1627. int ipa3_vote_for_bus_bw(uint32_t *bw_mbps)
  1628. {
  1629. int ret;
  1630. IPAWANDBG("Bus BW is %d\n", *bw_mbps);
  1631. if (bw_mbps == NULL) {
  1632. IPAWANERR("Bus BW is invalid\n");
  1633. return -EINVAL;
  1634. }
  1635. ret = ipa3_wwan_set_modem_perf_profile(*bw_mbps);
  1636. if (ret)
  1637. IPAWANERR("Failed to set perf profile to BW %u\n",
  1638. *bw_mbps);
  1639. else
  1640. IPAWANDBG("Succeeded to set perf profile to BW %u\n",
  1641. *bw_mbps);
  1642. return ret;
  1643. }
  1644. int ipa3_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req,
  1645. struct ipa_get_data_stats_resp_msg_v01 *resp)
  1646. {
  1647. struct ipa_msg_desc req_desc, resp_desc;
  1648. int rc;
  1649. req_desc.max_msg_len = QMI_IPA_GET_DATA_STATS_REQ_MAX_MSG_LEN_V01;
  1650. req_desc.msg_id = QMI_IPA_GET_DATA_STATS_REQ_V01;
  1651. req_desc.ei_array = ipa3_get_data_stats_req_msg_data_v01_ei;
  1652. resp_desc.max_msg_len = QMI_IPA_GET_DATA_STATS_RESP_MAX_MSG_LEN_V01;
  1653. resp_desc.msg_id = QMI_IPA_GET_DATA_STATS_RESP_V01;
  1654. resp_desc.ei_array = ipa3_get_data_stats_resp_msg_data_v01_ei;
  1655. IPAWANDBG_LOW("Sending QMI_IPA_GET_DATA_STATS_REQ_V01\n");
  1656. if (unlikely(!ipa_q6_clnt))
  1657. return -ETIMEDOUT;
  1658. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1659. &req_desc, req,
  1660. &resp_desc, resp,
  1661. QMI_SEND_STATS_REQ_TIMEOUT_MS);
  1662. if (rc < 0) {
  1663. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  1664. QMI_IPA_GET_DATA_STATS_REQ_V01,
  1665. rc);
  1666. return rc;
  1667. }
  1668. IPAWANDBG_LOW("QMI_IPA_GET_DATA_STATS_RESP_V01 received\n");
  1669. return ipa3_check_qmi_response(rc,
  1670. QMI_IPA_GET_DATA_STATS_REQ_V01, resp->resp.result,
  1671. resp->resp.error, "ipa_get_data_stats_resp_msg_v01");
  1672. }
  1673. int ipa3_qmi_get_network_stats(struct ipa_get_apn_data_stats_req_msg_v01 *req,
  1674. struct ipa_get_apn_data_stats_resp_msg_v01 *resp)
  1675. {
  1676. struct ipa_msg_desc req_desc, resp_desc;
  1677. int rc;
  1678. req_desc.max_msg_len = QMI_IPA_GET_APN_DATA_STATS_REQ_MAX_MSG_LEN_V01;
  1679. req_desc.msg_id = QMI_IPA_GET_APN_DATA_STATS_REQ_V01;
  1680. req_desc.ei_array = ipa3_get_apn_data_stats_req_msg_data_v01_ei;
  1681. resp_desc.max_msg_len = QMI_IPA_GET_APN_DATA_STATS_RESP_MAX_MSG_LEN_V01;
  1682. resp_desc.msg_id = QMI_IPA_GET_APN_DATA_STATS_RESP_V01;
  1683. resp_desc.ei_array = ipa3_get_apn_data_stats_resp_msg_data_v01_ei;
  1684. IPAWANDBG_LOW("Sending QMI_IPA_GET_APN_DATA_STATS_REQ_V01\n");
  1685. if (unlikely(!ipa_q6_clnt))
  1686. return -ETIMEDOUT;
  1687. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1688. &req_desc, req,
  1689. &resp_desc, resp,
  1690. QMI_SEND_STATS_REQ_TIMEOUT_MS);
  1691. if (rc < 0) {
  1692. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  1693. QMI_IPA_GET_APN_DATA_STATS_REQ_V01,
  1694. rc);
  1695. return rc;
  1696. }
  1697. IPAWANDBG_LOW("QMI_IPA_GET_APN_DATA_STATS_RESP_V01 received\n");
  1698. return ipa3_check_qmi_response(rc,
  1699. QMI_IPA_GET_APN_DATA_STATS_REQ_V01, resp->resp.result,
  1700. resp->resp.error, "ipa_get_apn_data_stats_req_msg_v01");
  1701. }
  1702. int ipa3_qmi_set_data_quota(struct ipa_set_data_usage_quota_req_msg_v01 *req)
  1703. {
  1704. struct ipa_set_data_usage_quota_resp_msg_v01 resp;
  1705. struct ipa_msg_desc req_desc, resp_desc;
  1706. int rc;
  1707. memset(&resp, 0, sizeof(struct ipa_set_data_usage_quota_resp_msg_v01));
  1708. req_desc.max_msg_len = QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_MAX_MSG_LEN_V01;
  1709. req_desc.msg_id = QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01;
  1710. req_desc.ei_array = ipa3_set_data_usage_quota_req_msg_data_v01_ei;
  1711. resp_desc.max_msg_len =
  1712. QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_MAX_MSG_LEN_V01;
  1713. resp_desc.msg_id = QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_V01;
  1714. resp_desc.ei_array = ipa3_set_data_usage_quota_resp_msg_data_v01_ei;
  1715. IPAWANDBG_LOW("Sending QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01\n");
  1716. if (unlikely(!ipa_q6_clnt))
  1717. return -ETIMEDOUT;
  1718. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1719. &req_desc, req,
  1720. &resp_desc, &resp,
  1721. QMI_SEND_STATS_REQ_TIMEOUT_MS);
  1722. if (rc < 0) {
  1723. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  1724. QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01,
  1725. rc);
  1726. return rc;
  1727. }
  1728. IPAWANDBG_LOW("QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_V01 received\n");
  1729. return ipa3_check_qmi_response(rc,
  1730. QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01, resp.resp.result,
  1731. resp.resp.error, "ipa_set_data_usage_quota_req_msg_v01");
  1732. }
  1733. int ipa3_qmi_set_aggr_info(enum ipa_aggr_enum_type_v01 aggr_enum_type)
  1734. {
  1735. struct ipa_mhi_prime_aggr_info_resp_msg_v01 resp;
  1736. struct ipa_msg_desc req_desc, resp_desc;
  1737. int rc;
  1738. IPAWANDBG("sending aggr_info_request\n");
  1739. /* replace to right qmap format */
  1740. aggr_req.aggr_info[1].aggr_type = aggr_enum_type;
  1741. aggr_req.aggr_info[2].aggr_type = aggr_enum_type;
  1742. aggr_req.aggr_info[3].aggr_type = aggr_enum_type;
  1743. aggr_req.aggr_info[4].aggr_type = aggr_enum_type;
  1744. memset(&resp, 0, sizeof(struct ipa_mhi_prime_aggr_info_resp_msg_v01));
  1745. req_desc.max_msg_len = IPA_MHI_PRIME_AGGR_INFO_REQ_MSG_V01_MAX_MSG_LEN;
  1746. req_desc.msg_id = QMI_IPA_MHI_PRIME_AGGR_INFO_REQ_V01;
  1747. req_desc.ei_array = ipa_mhi_prime_aggr_info_req_msg_v01_ei;
  1748. resp_desc.max_msg_len =
  1749. IPA_MHI_PRIME_AGGR_INFO_RESP_MSG_V01_MAX_MSG_LEN;
  1750. resp_desc.msg_id = QMI_IPA_MHI_PRIME_AGGR_INFO_RESP_V01;
  1751. resp_desc.ei_array = ipa_mhi_prime_aggr_info_resp_msg_v01_ei;
  1752. IPAWANDBG("Sending QMI_IPA_MHI_PRIME_AGGR_INFO_REQ_V01(%d)\n",
  1753. aggr_enum_type);
  1754. if (unlikely(!ipa_q6_clnt)) {
  1755. IPAWANERR(" ipa_q6_clnt not initialized\n");
  1756. return -ETIMEDOUT;
  1757. }
  1758. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1759. &req_desc, &aggr_req,
  1760. &resp_desc, &resp,
  1761. QMI_SEND_STATS_REQ_TIMEOUT_MS);
  1762. if (rc < 0) {
  1763. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  1764. QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01,
  1765. rc);
  1766. return rc;
  1767. }
  1768. IPAWANDBG_LOW("QMI_IPA_MHI_PRIME_AGGR_INFO_RESP_V01 received\n");
  1769. return ipa3_check_qmi_response(rc,
  1770. QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01, resp.resp.result,
  1771. resp.resp.error, "ipa_mhi_prime_aggr_info_req_msg_v01");
  1772. }
  1773. int ipa3_qmi_stop_data_qouta(void)
  1774. {
  1775. struct ipa_stop_data_usage_quota_req_msg_v01 req;
  1776. struct ipa_stop_data_usage_quota_resp_msg_v01 resp;
  1777. struct ipa_msg_desc req_desc, resp_desc;
  1778. int rc;
  1779. memset(&req, 0, sizeof(struct ipa_stop_data_usage_quota_req_msg_v01));
  1780. memset(&resp, 0, sizeof(struct ipa_stop_data_usage_quota_resp_msg_v01));
  1781. req_desc.max_msg_len =
  1782. QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_MAX_MSG_LEN_V01;
  1783. req_desc.msg_id = QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01;
  1784. req_desc.ei_array = ipa3_stop_data_usage_quota_req_msg_data_v01_ei;
  1785. resp_desc.max_msg_len =
  1786. QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_MAX_MSG_LEN_V01;
  1787. resp_desc.msg_id = QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_V01;
  1788. resp_desc.ei_array = ipa3_stop_data_usage_quota_resp_msg_data_v01_ei;
  1789. IPAWANDBG_LOW("Sending QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01\n");
  1790. if (unlikely(!ipa_q6_clnt))
  1791. return -ETIMEDOUT;
  1792. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1793. &req_desc, &req,
  1794. &resp_desc, &resp,
  1795. QMI_SEND_STATS_REQ_TIMEOUT_MS);
  1796. if (rc < 0) {
  1797. IPAWANERR("QMI send Req %d failed, rc= %d\n",
  1798. QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01,
  1799. rc);
  1800. return rc;
  1801. }
  1802. IPAWANDBG_LOW("QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_V01 received\n");
  1803. return ipa3_check_qmi_response(rc,
  1804. QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01, resp.resp.result,
  1805. resp.resp.error, "ipa_stop_data_usage_quota_req_msg_v01");
  1806. }
  1807. int ipa3_qmi_enable_per_client_stats(
  1808. struct ipa_enable_per_client_stats_req_msg_v01 *req,
  1809. struct ipa_enable_per_client_stats_resp_msg_v01 *resp)
  1810. {
  1811. struct ipa_msg_desc req_desc, resp_desc;
  1812. int rc = 0;
  1813. req_desc.max_msg_len =
  1814. QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_MAX_MSG_LEN_V01;
  1815. req_desc.msg_id =
  1816. QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01;
  1817. req_desc.ei_array =
  1818. ipa3_enable_per_client_stats_req_msg_data_v01_ei;
  1819. resp_desc.max_msg_len =
  1820. QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_MAX_MSG_LEN_V01;
  1821. resp_desc.msg_id =
  1822. QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_V01;
  1823. resp_desc.ei_array =
  1824. ipa3_enable_per_client_stats_resp_msg_data_v01_ei;
  1825. IPAWANDBG("Sending QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01\n");
  1826. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1827. &req_desc, req,
  1828. &resp_desc, resp,
  1829. QMI_SEND_STATS_REQ_TIMEOUT_MS);
  1830. if (rc < 0) {
  1831. IPAWANERR("send Req %d failed, rc= %d\n",
  1832. QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01,
  1833. rc);
  1834. return rc;
  1835. }
  1836. IPAWANDBG("QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_V01 received\n");
  1837. return ipa3_check_qmi_response(rc,
  1838. QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01, resp->resp.result,
  1839. resp->resp.error, "ipa3_qmi_enable_per_client_stats");
  1840. }
  1841. int ipa3_qmi_get_per_client_packet_stats(
  1842. struct ipa_get_stats_per_client_req_msg_v01 *req,
  1843. struct ipa_get_stats_per_client_resp_msg_v01 *resp)
  1844. {
  1845. struct ipa_msg_desc req_desc, resp_desc;
  1846. int rc;
  1847. req_desc.max_msg_len = QMI_IPA_GET_STATS_PER_CLIENT_REQ_MAX_MSG_LEN_V01;
  1848. req_desc.msg_id = QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01;
  1849. req_desc.ei_array = ipa3_get_stats_per_client_req_msg_data_v01_ei;
  1850. resp_desc.max_msg_len =
  1851. QMI_IPA_GET_STATS_PER_CLIENT_RESP_MAX_MSG_LEN_V01;
  1852. resp_desc.msg_id = QMI_IPA_GET_STATS_PER_CLIENT_RESP_V01;
  1853. resp_desc.ei_array = ipa3_get_stats_per_client_resp_msg_data_v01_ei;
  1854. IPAWANDBG("Sending QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01\n");
  1855. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1856. &req_desc, req,
  1857. &resp_desc, resp,
  1858. QMI_SEND_STATS_REQ_TIMEOUT_MS);
  1859. if (rc < 0) {
  1860. IPAWANERR("send Req %d failed, rc= %d\n",
  1861. QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01,
  1862. rc);
  1863. return rc;
  1864. }
  1865. IPAWANDBG("QMI_IPA_GET_STATS_PER_CLIENT_RESP_V01 received\n");
  1866. return ipa3_check_qmi_response(rc,
  1867. QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01, resp->resp.result,
  1868. resp->resp.error,
  1869. "struct ipa_get_stats_per_client_req_msg_v01");
  1870. }
  1871. int ipa3_qmi_send_mhi_ready_indication(
  1872. struct ipa_mhi_ready_indication_msg_v01 *req)
  1873. {
  1874. IPAWANDBG("Sending QMI_IPA_MHI_READY_IND_V01\n");
  1875. if (unlikely(!ipa3_svc_handle))
  1876. return -ETIMEDOUT;
  1877. return qmi_send_indication(ipa3_svc_handle,
  1878. &ipa3_qmi_ctx->client_sq,
  1879. QMI_IPA_MHI_READY_IND_V01,
  1880. IPA_MHI_READY_INDICATION_MSG_V01_MAX_MSG_LEN,
  1881. ipa_mhi_ready_indication_msg_v01_ei,
  1882. req);
  1883. }
  1884. int ipa3_qmi_send_mhi_cleanup_request(struct ipa_mhi_cleanup_req_msg_v01 *req)
  1885. {
  1886. struct ipa_msg_desc req_desc, resp_desc;
  1887. struct ipa_mhi_cleanup_resp_msg_v01 resp;
  1888. int rc;
  1889. memset(&resp, 0, sizeof(resp));
  1890. IPAWANDBG("Sending QMI_IPA_MHI_CLEANUP_REQ_V01\n");
  1891. if (unlikely(!ipa_q6_clnt))
  1892. return -ETIMEDOUT;
  1893. req_desc.max_msg_len = IPA_MHI_CLK_VOTE_REQ_MSG_V01_MAX_MSG_LEN;
  1894. req_desc.msg_id = QMI_IPA_MHI_CLEANUP_REQ_V01;
  1895. req_desc.ei_array = ipa_mhi_cleanup_req_msg_v01_ei;
  1896. resp_desc.max_msg_len = IPA_MHI_CLK_VOTE_RESP_MSG_V01_MAX_MSG_LEN;
  1897. resp_desc.msg_id = QMI_IPA_MHI_CLEANUP_RESP_V01;
  1898. resp_desc.ei_array = ipa_mhi_cleanup_resp_msg_v01_ei;
  1899. rc = ipa3_qmi_send_req_wait(ipa_q6_clnt,
  1900. &req_desc, req,
  1901. &resp_desc, &resp,
  1902. QMI_MHI_SEND_REQ_TIMEOUT_MS);
  1903. IPAWANDBG("QMI_IPA_MHI_CLEANUP_RESP_V01 received\n");
  1904. return ipa3_check_qmi_response(rc,
  1905. QMI_IPA_MHI_CLEANUP_REQ_V01, resp.resp.result,
  1906. resp.resp.error, "ipa_mhi_cleanup_req_msg");
  1907. }
  1908. int ipa3_qmi_send_rsc_pipe_indication(
  1909. struct ipa_endp_desc_indication_msg_v01 *req)
  1910. {
  1911. IPAWANDBG("Sending QMI_IPA_ENDP_DESC_INDICATION_V01\n");
  1912. if (unlikely(!ipa3_svc_handle))
  1913. return -ETIMEDOUT;
  1914. return qmi_send_indication(ipa3_svc_handle,
  1915. &ipa3_qmi_ctx->client_sq,
  1916. QMI_IPA_ENDP_DESC_INDICATION_V01,
  1917. IPA_ENDP_DESC_INDICATION_MSG_V01_MAX_MSG_LEN,
  1918. ipa_endp_desc_indication_msg_v01_ei,
  1919. req);
  1920. }
  1921. void ipa3_qmi_init(void)
  1922. {
  1923. mutex_init(&ipa3_qmi_lock);
  1924. }
  1925. void ipa3_qmi_cleanup(void)
  1926. {
  1927. mutex_destroy(&ipa3_qmi_lock);
  1928. }