wmi_unified_sta_tlv.c 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518
  1. /*
  2. * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include <osdep.h>
  19. #include "wmi.h"
  20. #include "wmi_version.h"
  21. #include "wmi_unified_priv.h"
  22. #include "wmi_unified_sta_param.h"
  23. #include "wmi_unified_sta_api.h"
  24. /**
  25. * send_set_sta_sa_query_param_cmd_tlv() - set sta sa query parameters
  26. * @wmi_handle: wmi handle
  27. * @vdev_id: vdev id
  28. * @max_retries: max retries
  29. * @retry_interval: retry interval
  30. * This function sets sta query related parameters in fw.
  31. *
  32. * Return: QDF_STATUS_SUCCESS for success otherwise failure
  33. */
  34. static QDF_STATUS send_set_sta_sa_query_param_cmd_tlv(wmi_unified_t wmi_handle,
  35. uint8_t vdev_id,
  36. uint32_t max_retries,
  37. uint32_t retry_interval)
  38. {
  39. wmi_buf_t buf;
  40. WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *cmd;
  41. int len;
  42. len = sizeof(*cmd);
  43. buf = wmi_buf_alloc(wmi_handle, len);
  44. if (!buf) {
  45. return QDF_STATUS_E_FAILURE;
  46. }
  47. cmd = (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param *)wmi_buf_data(buf);
  48. WMITLV_SET_HDR(&cmd->tlv_header,
  49. WMITLV_TAG_STRUC_WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param,
  50. WMITLV_GET_STRUCT_TLVLEN
  51. (WMI_PMF_OFFLOAD_SET_SA_QUERY_CMD_fixed_param));
  52. cmd->vdev_id = vdev_id;
  53. cmd->sa_query_max_retry_count = max_retries;
  54. cmd->sa_query_retry_interval = retry_interval;
  55. WMI_LOGD(FL("STA sa query: vdev_id:%d interval:%u retry count:%d"),
  56. vdev_id, retry_interval, max_retries);
  57. wmi_mtrace(WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID, cmd->vdev_id, 0);
  58. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  59. WMI_PMF_OFFLOAD_SET_SA_QUERY_CMDID)) {
  60. WMI_LOGE(FL("Failed to offload STA SA Query"));
  61. wmi_buf_free(buf);
  62. return QDF_STATUS_E_FAILURE;
  63. }
  64. WMI_LOGD(FL("Exit :"));
  65. return 0;
  66. }
  67. /**
  68. * send_set_sta_keep_alive_cmd_tlv() - set sta keep alive parameters
  69. * @wmi_handle: wmi handle
  70. * @params: sta keep alive parameter
  71. *
  72. * This function sets keep alive related parameters in fw.
  73. *
  74. * Return: CDF status
  75. */
  76. static QDF_STATUS send_set_sta_keep_alive_cmd_tlv(wmi_unified_t wmi_handle,
  77. struct sta_params *params)
  78. {
  79. wmi_buf_t buf;
  80. WMI_STA_KEEPALIVE_CMD_fixed_param *cmd;
  81. WMI_STA_KEEPALVE_ARP_RESPONSE *arp_rsp;
  82. uint8_t *buf_ptr;
  83. int len;
  84. QDF_STATUS ret;
  85. WMI_LOGD("%s: Enter", __func__);
  86. len = sizeof(*cmd) + sizeof(*arp_rsp);
  87. buf = wmi_buf_alloc(wmi_handle, len);
  88. if (!buf) {
  89. return QDF_STATUS_E_FAILURE;
  90. }
  91. cmd = (WMI_STA_KEEPALIVE_CMD_fixed_param *) wmi_buf_data(buf);
  92. buf_ptr = (uint8_t *) cmd;
  93. WMITLV_SET_HDR(&cmd->tlv_header,
  94. WMITLV_TAG_STRUC_WMI_STA_KEEPALIVE_CMD_fixed_param,
  95. WMITLV_GET_STRUCT_TLVLEN
  96. (WMI_STA_KEEPALIVE_CMD_fixed_param));
  97. cmd->interval = params->timeperiod;
  98. cmd->enable = (params->timeperiod) ? 1 : 0;
  99. cmd->vdev_id = params->vdev_id;
  100. WMI_LOGD("Keep Alive: vdev_id:%d interval:%u method:%d", params->vdev_id,
  101. params->timeperiod, params->method);
  102. arp_rsp = (WMI_STA_KEEPALVE_ARP_RESPONSE *) (buf_ptr + sizeof(*cmd));
  103. WMITLV_SET_HDR(&arp_rsp->tlv_header,
  104. WMITLV_TAG_STRUC_WMI_STA_KEEPALVE_ARP_RESPONSE,
  105. WMITLV_GET_STRUCT_TLVLEN(WMI_STA_KEEPALVE_ARP_RESPONSE));
  106. if ((params->method == WMI_KEEP_ALIVE_UNSOLICIT_ARP_RSP) ||
  107. (params->method ==
  108. WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST)) {
  109. if ((NULL == params->hostv4addr) ||
  110. (NULL == params->destv4addr) ||
  111. (NULL == params->destmac)) {
  112. WMI_LOGE("%s: received null pointer, hostv4addr:%pK "
  113. "destv4addr:%pK destmac:%pK ", __func__,
  114. params->hostv4addr, params->destv4addr,
  115. params->destmac);
  116. wmi_buf_free(buf);
  117. return QDF_STATUS_E_FAILURE;
  118. }
  119. cmd->method = params->method;
  120. qdf_mem_copy(&arp_rsp->sender_prot_addr, params->hostv4addr,
  121. WMI_IPV4_ADDR_LEN);
  122. qdf_mem_copy(&arp_rsp->target_prot_addr, params->destv4addr,
  123. WMI_IPV4_ADDR_LEN);
  124. WMI_CHAR_ARRAY_TO_MAC_ADDR(params->destmac, &arp_rsp->dest_mac_addr);
  125. } else {
  126. cmd->method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
  127. }
  128. wmi_mtrace(WMI_STA_KEEPALIVE_CMDID, cmd->vdev_id, 0);
  129. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  130. WMI_STA_KEEPALIVE_CMDID);
  131. if (QDF_IS_STATUS_ERROR(ret)) {
  132. WMI_LOGE("Failed to set KeepAlive");
  133. wmi_buf_free(buf);
  134. }
  135. WMI_LOGD("%s: Exit", __func__);
  136. return ret;
  137. }
  138. /**
  139. * send_vdev_set_gtx_cfg_cmd_tlv() - set GTX params
  140. * @wmi_handle: wmi handle
  141. * @if_id: vdev id
  142. * @gtx_info: GTX config params
  143. *
  144. * This function set GTX related params in firmware.
  145. *
  146. * Return: QDF_STATUS_SUCCESS for success or error code
  147. */
  148. static QDF_STATUS send_vdev_set_gtx_cfg_cmd_tlv(wmi_unified_t wmi_handle, uint32_t if_id,
  149. struct wmi_gtx_config *gtx_info)
  150. {
  151. wmi_vdev_set_gtx_params_cmd_fixed_param *cmd;
  152. wmi_buf_t buf;
  153. QDF_STATUS ret;
  154. int len = sizeof(wmi_vdev_set_gtx_params_cmd_fixed_param);
  155. buf = wmi_buf_alloc(wmi_handle, len);
  156. if (!buf) {
  157. return QDF_STATUS_E_NOMEM;
  158. }
  159. cmd = (wmi_vdev_set_gtx_params_cmd_fixed_param *) wmi_buf_data(buf);
  160. WMITLV_SET_HDR(&cmd->tlv_header,
  161. WMITLV_TAG_STRUC_wmi_vdev_set_gtx_params_cmd_fixed_param,
  162. WMITLV_GET_STRUCT_TLVLEN
  163. (wmi_vdev_set_gtx_params_cmd_fixed_param));
  164. cmd->vdev_id = if_id;
  165. cmd->gtxRTMask[0] = gtx_info->gtx_rt_mask[0];
  166. cmd->gtxRTMask[1] = gtx_info->gtx_rt_mask[1];
  167. cmd->userGtxMask = gtx_info->gtx_usrcfg;
  168. cmd->gtxPERThreshold = gtx_info->gtx_threshold;
  169. cmd->gtxPERMargin = gtx_info->gtx_margin;
  170. cmd->gtxTPCstep = gtx_info->gtx_tpcstep;
  171. cmd->gtxTPCMin = gtx_info->gtx_tpcmin;
  172. cmd->gtxBWMask = gtx_info->gtx_bwmask;
  173. WMI_LOGD("Setting vdev%d GTX values:htmcs 0x%x, vhtmcs 0x%x, usermask 0x%x, \
  174. gtxPERThreshold %d, gtxPERMargin %d, gtxTPCstep %d, gtxTPCMin %d, \
  175. gtxBWMask 0x%x.", if_id, cmd->gtxRTMask[0], cmd->gtxRTMask[1],
  176. cmd->userGtxMask, cmd->gtxPERThreshold, cmd->gtxPERMargin,
  177. cmd->gtxTPCstep, cmd->gtxTPCMin, cmd->gtxBWMask);
  178. wmi_mtrace(WMI_VDEV_SET_GTX_PARAMS_CMDID, cmd->vdev_id, 0);
  179. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  180. WMI_VDEV_SET_GTX_PARAMS_CMDID);
  181. if (QDF_IS_STATUS_ERROR(ret)) {
  182. WMI_LOGE("Failed to set GTX PARAMS");
  183. wmi_buf_free(buf);
  184. }
  185. return ret;
  186. }
  187. /**
  188. * send_process_dhcp_ind_cmd_tlv() - process dhcp indication from SME
  189. * @wmi_handle: wmi handle
  190. * @ta_dhcp_ind: DHCP indication parameter
  191. *
  192. * Return: CDF Status
  193. */
  194. static QDF_STATUS send_process_dhcp_ind_cmd_tlv(wmi_unified_t wmi_handle,
  195. wmi_peer_set_param_cmd_fixed_param *ta_dhcp_ind)
  196. {
  197. QDF_STATUS status;
  198. wmi_buf_t buf = NULL;
  199. uint8_t *buf_ptr;
  200. wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp;
  201. int len = sizeof(wmi_peer_set_param_cmd_fixed_param);
  202. buf = wmi_buf_alloc(wmi_handle, len);
  203. if (!buf) {
  204. return QDF_STATUS_E_NOMEM;
  205. }
  206. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  207. peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr;
  208. WMITLV_SET_HDR(&peer_set_param_fp->tlv_header,
  209. WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param,
  210. WMITLV_GET_STRUCT_TLVLEN
  211. (wmi_peer_set_param_cmd_fixed_param));
  212. /* fill in values */
  213. peer_set_param_fp->vdev_id = ta_dhcp_ind->vdev_id;
  214. peer_set_param_fp->param_id = ta_dhcp_ind->param_id;
  215. peer_set_param_fp->param_value = ta_dhcp_ind->param_value;
  216. qdf_mem_copy(&peer_set_param_fp->peer_macaddr,
  217. &ta_dhcp_ind->peer_macaddr,
  218. sizeof(ta_dhcp_ind->peer_macaddr));
  219. wmi_mtrace(WMI_PEER_SET_PARAM_CMDID, NO_SESSION, 0);
  220. status = wmi_unified_cmd_send(wmi_handle, buf,
  221. len, WMI_PEER_SET_PARAM_CMDID);
  222. if (QDF_IS_STATUS_ERROR(status)) {
  223. WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
  224. " returned Error %d", __func__, status);
  225. wmi_buf_free(buf);
  226. }
  227. return status;
  228. }
  229. /**
  230. * send_get_link_speed_cmd_tlv() -send command to get linkspeed
  231. * @wmi_handle: wmi handle
  232. * @pLinkSpeed: link speed info
  233. *
  234. * Return: CDF status
  235. */
  236. static QDF_STATUS send_get_link_speed_cmd_tlv(wmi_unified_t wmi_handle,
  237. wmi_mac_addr peer_macaddr)
  238. {
  239. wmi_peer_get_estimated_linkspeed_cmd_fixed_param *cmd;
  240. wmi_buf_t wmi_buf;
  241. uint32_t len;
  242. uint8_t *buf_ptr;
  243. len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param);
  244. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  245. if (!wmi_buf) {
  246. return QDF_STATUS_E_NOMEM;
  247. }
  248. buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
  249. cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *) buf_ptr;
  250. WMITLV_SET_HDR(&cmd->tlv_header,
  251. WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param,
  252. WMITLV_GET_STRUCT_TLVLEN
  253. (wmi_peer_get_estimated_linkspeed_cmd_fixed_param));
  254. /* Copy the peer macaddress to the wma buffer */
  255. qdf_mem_copy(&cmd->peer_macaddr,
  256. &peer_macaddr,
  257. sizeof(peer_macaddr));
  258. wmi_mtrace(WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID, cmd->vdev_id, 0);
  259. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  260. WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) {
  261. WMI_LOGE("%s: failed to send link speed command", __func__);
  262. wmi_buf_free(wmi_buf);
  263. return QDF_STATUS_E_FAILURE;
  264. }
  265. return QDF_STATUS_SUCCESS;
  266. }
  267. /**
  268. * send_fw_profiling_cmd_tlv() - send FW profiling cmd to WLAN FW
  269. * @wmi_handl: wmi handle
  270. * @cmd: Profiling command index
  271. * @value1: parameter1 value
  272. * @value2: parameter2 value
  273. *
  274. * Return: QDF_STATUS_SUCCESS for success else error code
  275. */
  276. static QDF_STATUS send_fw_profiling_cmd_tlv(wmi_unified_t wmi_handle,
  277. uint32_t cmd, uint32_t value1, uint32_t value2)
  278. {
  279. wmi_buf_t buf;
  280. int32_t len = 0;
  281. int ret;
  282. wmi_wlan_profile_trigger_cmd_fixed_param *prof_trig_cmd;
  283. wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *hist_intvl_cmd;
  284. wmi_wlan_profile_enable_profile_id_cmd_fixed_param *profile_enable_cmd;
  285. wmi_wlan_profile_get_prof_data_cmd_fixed_param *profile_getdata_cmd;
  286. switch (cmd) {
  287. case WMI_WLAN_PROFILE_TRIGGER_CMDID:
  288. len = sizeof(wmi_wlan_profile_trigger_cmd_fixed_param);
  289. buf = wmi_buf_alloc(wmi_handle, len);
  290. if (!buf) {
  291. return QDF_STATUS_E_NOMEM;
  292. }
  293. prof_trig_cmd =
  294. (wmi_wlan_profile_trigger_cmd_fixed_param *)
  295. wmi_buf_data(buf);
  296. WMITLV_SET_HDR(&prof_trig_cmd->tlv_header,
  297. WMITLV_TAG_STRUC_wmi_wlan_profile_trigger_cmd_fixed_param,
  298. WMITLV_GET_STRUCT_TLVLEN
  299. (wmi_wlan_profile_trigger_cmd_fixed_param));
  300. prof_trig_cmd->enable = value1;
  301. wmi_mtrace(WMI_WLAN_PROFILE_TRIGGER_CMDID, NO_SESSION, 0);
  302. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  303. WMI_WLAN_PROFILE_TRIGGER_CMDID);
  304. if (ret) {
  305. WMI_LOGE("PROFILE_TRIGGER cmd Failed with value %d",
  306. value1);
  307. wmi_buf_free(buf);
  308. return ret;
  309. }
  310. break;
  311. case WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID:
  312. len = sizeof(wmi_wlan_profile_get_prof_data_cmd_fixed_param);
  313. buf = wmi_buf_alloc(wmi_handle, len);
  314. if (!buf) {
  315. return QDF_STATUS_E_NOMEM;
  316. }
  317. profile_getdata_cmd =
  318. (wmi_wlan_profile_get_prof_data_cmd_fixed_param *)
  319. wmi_buf_data(buf);
  320. WMITLV_SET_HDR(&profile_getdata_cmd->tlv_header,
  321. WMITLV_TAG_STRUC_wmi_wlan_profile_get_prof_data_cmd_fixed_param,
  322. WMITLV_GET_STRUCT_TLVLEN
  323. (wmi_wlan_profile_get_prof_data_cmd_fixed_param));
  324. wmi_mtrace(WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
  325. NO_SESSION, 0);
  326. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  327. WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID);
  328. if (ret) {
  329. WMI_LOGE("PROFILE_DATA cmd Failed for id %d value %d",
  330. value1, value2);
  331. wmi_buf_free(buf);
  332. return ret;
  333. }
  334. break;
  335. case WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID:
  336. len = sizeof(wmi_wlan_profile_set_hist_intvl_cmd_fixed_param);
  337. buf = wmi_buf_alloc(wmi_handle, len);
  338. if (!buf) {
  339. return QDF_STATUS_E_NOMEM;
  340. }
  341. hist_intvl_cmd =
  342. (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param *)
  343. wmi_buf_data(buf);
  344. WMITLV_SET_HDR(&hist_intvl_cmd->tlv_header,
  345. WMITLV_TAG_STRUC_wmi_wlan_profile_set_hist_intvl_cmd_fixed_param,
  346. WMITLV_GET_STRUCT_TLVLEN
  347. (wmi_wlan_profile_set_hist_intvl_cmd_fixed_param));
  348. hist_intvl_cmd->profile_id = value1;
  349. hist_intvl_cmd->value = value2;
  350. wmi_mtrace(WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
  351. NO_SESSION, 0);
  352. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  353. WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID);
  354. if (ret) {
  355. WMI_LOGE("HIST_INTVL cmd Failed for id %d value %d",
  356. value1, value2);
  357. wmi_buf_free(buf);
  358. return ret;
  359. }
  360. break;
  361. case WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID:
  362. len =
  363. sizeof(wmi_wlan_profile_enable_profile_id_cmd_fixed_param);
  364. buf = wmi_buf_alloc(wmi_handle, len);
  365. if (!buf) {
  366. return QDF_STATUS_E_NOMEM;
  367. }
  368. profile_enable_cmd =
  369. (wmi_wlan_profile_enable_profile_id_cmd_fixed_param *)
  370. wmi_buf_data(buf);
  371. WMITLV_SET_HDR(&profile_enable_cmd->tlv_header,
  372. WMITLV_TAG_STRUC_wmi_wlan_profile_enable_profile_id_cmd_fixed_param,
  373. WMITLV_GET_STRUCT_TLVLEN
  374. (wmi_wlan_profile_enable_profile_id_cmd_fixed_param));
  375. profile_enable_cmd->profile_id = value1;
  376. profile_enable_cmd->enable = value2;
  377. wmi_mtrace(WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
  378. NO_SESSION, 0);
  379. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  380. WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID);
  381. if (ret) {
  382. WMI_LOGE("enable cmd Failed for id %d value %d",
  383. value1, value2);
  384. wmi_buf_free(buf);
  385. return ret;
  386. }
  387. break;
  388. default:
  389. WMI_LOGD("%s: invalid profiling command", __func__);
  390. break;
  391. }
  392. return 0;
  393. }
  394. /**
  395. * send_nat_keepalive_en_cmd_tlv() - enable NAT keepalive filter
  396. * @wmi_handle: wmi handle
  397. * @vdev_id: vdev id
  398. *
  399. * Return: QDF_STATUS_SUCCESS for success or error code
  400. */
  401. static QDF_STATUS send_nat_keepalive_en_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id)
  402. {
  403. WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *cmd;
  404. wmi_buf_t buf;
  405. int32_t len = sizeof(*cmd);
  406. WMI_LOGD("%s: vdev_id %d", __func__, vdev_id);
  407. buf = wmi_buf_alloc(wmi_handle, len);
  408. if (!buf) {
  409. return QDF_STATUS_E_NOMEM;
  410. }
  411. cmd = (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param *)
  412. wmi_buf_data(buf);
  413. WMITLV_SET_HDR(&cmd->tlv_header,
  414. WMITLV_TAG_STRUC_WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param,
  415. WMITLV_GET_STRUCT_TLVLEN
  416. (WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD_fixed_param));
  417. cmd->vdev_id = vdev_id;
  418. cmd->action = IPSEC_NATKEEPALIVE_FILTER_ENABLE;
  419. wmi_mtrace(WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, cmd->vdev_id, 0);
  420. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  421. WMI_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID)) {
  422. WMI_LOGP("%s: Failed to send NAT keepalive enable command",
  423. __func__);
  424. wmi_buf_free(buf);
  425. return QDF_STATUS_E_FAILURE;
  426. }
  427. return 0;
  428. }
  429. static QDF_STATUS send_wlm_latency_level_cmd_tlv(wmi_unified_t wmi_handle,
  430. struct wlm_latency_level_param *params)
  431. {
  432. wmi_wlm_config_cmd_fixed_param *cmd;
  433. wmi_buf_t buf;
  434. uint32_t len = sizeof(*cmd);
  435. static uint32_t ll[4] = {100, 60, 40, 20};
  436. buf = wmi_buf_alloc(wmi_handle, len);
  437. if (!buf) {
  438. return QDF_STATUS_E_NOMEM;
  439. }
  440. cmd = (wmi_wlm_config_cmd_fixed_param *)wmi_buf_data(buf);
  441. WMITLV_SET_HDR(&cmd->tlv_header,
  442. WMITLV_TAG_STRUC_wmi_wlm_config_cmd_fixed_param,
  443. WMITLV_GET_STRUCT_TLVLEN
  444. (wmi_wlm_config_cmd_fixed_param));
  445. cmd->vdev_id = params->vdev_id;
  446. cmd->latency_level = params->wlm_latency_level;
  447. cmd->ul_latency = ll[params->wlm_latency_level];
  448. cmd->dl_latency = ll[params->wlm_latency_level];
  449. cmd->flags = params->wlm_latency_flags;
  450. wmi_mtrace(WMI_WLM_CONFIG_CMDID, cmd->vdev_id, 0);
  451. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  452. WMI_WLM_CONFIG_CMDID)) {
  453. WMI_LOGE("%s: Failed to send setting latency config command",
  454. __func__);
  455. wmi_buf_free(buf);
  456. return QDF_STATUS_E_FAILURE;
  457. }
  458. return 0;
  459. }
  460. #ifdef WLAN_FEATURE_NAN
  461. /**
  462. * send_nan_req_cmd_tlv() - to send nan request to target
  463. * @wmi_handle: wmi handle
  464. * @nan_req: request data which will be non-null
  465. *
  466. * Return: CDF status
  467. */
  468. static QDF_STATUS send_nan_req_cmd_tlv(wmi_unified_t wmi_handle,
  469. struct nan_req_params *nan_req)
  470. {
  471. QDF_STATUS ret;
  472. wmi_nan_cmd_param *cmd;
  473. wmi_buf_t buf;
  474. uint16_t len = sizeof(*cmd);
  475. uint16_t nan_data_len, nan_data_len_aligned;
  476. uint8_t *buf_ptr;
  477. /*
  478. * <----- cmd ------------><-- WMI_TLV_HDR_SIZE --><--- data ---->
  479. * +------------+----------+-----------------------+--------------+
  480. * | tlv_header | data_len | WMITLV_TAG_ARRAY_BYTE | nan_req_data |
  481. * +------------+----------+-----------------------+--------------+
  482. */
  483. if (!nan_req) {
  484. WMI_LOGE("%s:nan req is not valid", __func__);
  485. return QDF_STATUS_E_FAILURE;
  486. }
  487. nan_data_len = nan_req->request_data_len;
  488. nan_data_len_aligned = roundup(nan_req->request_data_len,
  489. sizeof(uint32_t));
  490. if (nan_data_len_aligned < nan_req->request_data_len) {
  491. WMI_LOGE("%s: integer overflow while rounding up data_len",
  492. __func__);
  493. return QDF_STATUS_E_FAILURE;
  494. }
  495. if (nan_data_len_aligned > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE) {
  496. WMI_LOGE("%s: wmi_max_msg_size overflow for given datalen",
  497. __func__);
  498. return QDF_STATUS_E_FAILURE;
  499. }
  500. len += WMI_TLV_HDR_SIZE + nan_data_len_aligned;
  501. buf = wmi_buf_alloc(wmi_handle, len);
  502. if (!buf) {
  503. return QDF_STATUS_E_NOMEM;
  504. }
  505. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  506. cmd = (wmi_nan_cmd_param *) buf_ptr;
  507. WMITLV_SET_HDR(&cmd->tlv_header,
  508. WMITLV_TAG_STRUC_wmi_nan_cmd_param,
  509. WMITLV_GET_STRUCT_TLVLEN(wmi_nan_cmd_param));
  510. cmd->data_len = nan_req->request_data_len;
  511. WMI_LOGD("%s: The data len value is %u",
  512. __func__, nan_req->request_data_len);
  513. buf_ptr += sizeof(wmi_nan_cmd_param);
  514. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, nan_data_len_aligned);
  515. buf_ptr += WMI_TLV_HDR_SIZE;
  516. qdf_mem_copy(buf_ptr, nan_req->request_data, cmd->data_len);
  517. wmi_mtrace(WMI_NAN_CMDID, NO_SESSION, 0);
  518. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  519. WMI_NAN_CMDID);
  520. if (QDF_IS_STATUS_ERROR(ret)) {
  521. WMI_LOGE("%s Failed to send set param command ret = %d",
  522. __func__, ret);
  523. wmi_buf_free(buf);
  524. }
  525. return ret;
  526. }
  527. void wmi_nan_feature_attach_tlv(struct wmi_unified *wmi_handle)
  528. {
  529. struct wmi_ops *ops = wmi_handle->ops;
  530. ops->send_nan_req_cmd = send_nan_req_cmd_tlv;
  531. }
  532. #endif /* WLAN_FEATURE_NAN */
  533. #ifdef CONVERGED_TDLS_ENABLE
  534. /**
  535. * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode
  536. * @tdls_sw_mode: tdls_sw_mode
  537. *
  538. * This function returns wmi tdls offchannel mode
  539. *
  540. * Return: enum value of wmi tdls offchannel mode
  541. */
  542. static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode)
  543. {
  544. uint8_t off_chan_mode;
  545. switch (tdls_sw_mode) {
  546. case ENABLE_CHANSWITCH:
  547. off_chan_mode = WMI_TDLS_ENABLE_OFFCHANNEL;
  548. break;
  549. case DISABLE_CHANSWITCH:
  550. off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
  551. break;
  552. default:
  553. WMI_LOGD(FL("unknown tdls_sw_mode %d"), tdls_sw_mode);
  554. off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
  555. }
  556. return off_chan_mode;
  557. }
  558. /**
  559. * tdls_get_wmi_offchannel_bw - Get WMI tdls off channel Bandwidth
  560. * @tdls_sw_mode: tdls_sw_mode
  561. *
  562. * This function returns wmi tdls offchannel bandwidth
  563. *
  564. * Return: TDLS offchannel bandwidth
  565. */
  566. static uint8_t tdls_get_wmi_offchannel_bw(uint16_t tdls_off_ch_bw_offset)
  567. {
  568. uint8_t off_chan_bw;
  569. switch (tdls_off_ch_bw_offset) {
  570. case BW20:
  571. off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
  572. break;
  573. case BW40_LOW_PRIMARY:
  574. case BW40_HIGH_PRIMARY:
  575. off_chan_bw = WMI_TDLS_OFFCHAN_40MHZ;
  576. break;
  577. case BW80:
  578. off_chan_bw = WMI_TDLS_OFFCHAN_80MHZ;
  579. case BWALL:
  580. off_chan_bw = WMI_TDLS_OFFCHAN_160MHZ;
  581. default:
  582. WMI_LOGD(FL("unknown tdls offchannel bw offset %d"),
  583. tdls_off_ch_bw_offset);
  584. off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
  585. }
  586. return off_chan_bw;
  587. }
  588. /**
  589. * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
  590. * @wmi_handle: wmi handle
  591. * @chan_switch_params: Pointer to tdls channel switch parameter structure
  592. *
  593. * This function sets tdls off channel mode
  594. *
  595. * Return: 0 on success; Negative errno otherwise
  596. */
  597. static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
  598. struct tdls_channel_switch_params *chan_switch_params)
  599. {
  600. wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
  601. wmi_buf_t wmi_buf;
  602. u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
  603. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  604. if (!wmi_buf) {
  605. return QDF_STATUS_E_FAILURE;
  606. }
  607. cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
  608. wmi_buf_data(wmi_buf);
  609. WMITLV_SET_HDR(&cmd->tlv_header,
  610. WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
  611. WMITLV_GET_STRUCT_TLVLEN(
  612. wmi_tdls_set_offchan_mode_cmd_fixed_param));
  613. WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
  614. &cmd->peer_macaddr);
  615. cmd->vdev_id = chan_switch_params->vdev_id;
  616. cmd->offchan_mode =
  617. tdls_get_wmi_offchannel_mode(chan_switch_params->tdls_sw_mode);
  618. cmd->is_peer_responder = chan_switch_params->is_responder;
  619. cmd->offchan_num = chan_switch_params->tdls_off_ch;
  620. cmd->offchan_bw_bitmap =
  621. tdls_get_wmi_offchannel_bw(
  622. chan_switch_params->tdls_off_ch_bw_offset);
  623. cmd->offchan_oper_class = chan_switch_params->oper_class;
  624. WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
  625. cmd->peer_macaddr.mac_addr31to0,
  626. cmd->peer_macaddr.mac_addr47to32);
  627. WMI_LOGD(FL(
  628. "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
  629. "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d"
  630. ),
  631. cmd->vdev_id,
  632. cmd->offchan_mode,
  633. cmd->offchan_num,
  634. cmd->offchan_bw_bitmap,
  635. cmd->is_peer_responder,
  636. cmd->offchan_oper_class);
  637. wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0);
  638. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  639. WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
  640. WMI_LOGP(FL("failed to send tdls off chan command"));
  641. wmi_buf_free(wmi_buf);
  642. return QDF_STATUS_E_FAILURE;
  643. }
  644. return QDF_STATUS_SUCCESS;
  645. }
  646. /**
  647. * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
  648. * @wmi_handle: wmi handle
  649. * @pwmaTdlsparams: TDLS params
  650. *
  651. * Return: 0 for success or error code
  652. */
  653. static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
  654. void *tdls_param, uint8_t tdls_state)
  655. {
  656. wmi_tdls_set_state_cmd_fixed_param *cmd;
  657. wmi_buf_t wmi_buf;
  658. struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param;
  659. uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
  660. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  661. if (!wmi_buf) {
  662. return QDF_STATUS_E_FAILURE;
  663. }
  664. cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
  665. WMITLV_SET_HDR(&cmd->tlv_header,
  666. WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
  667. WMITLV_GET_STRUCT_TLVLEN
  668. (wmi_tdls_set_state_cmd_fixed_param));
  669. cmd->vdev_id = wmi_tdls->vdev_id;
  670. cmd->state = tdls_state;
  671. cmd->notification_interval_ms = wmi_tdls->notification_interval_ms;
  672. cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold;
  673. cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold;
  674. cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold;
  675. cmd->rssi_delta = wmi_tdls->rssi_delta;
  676. cmd->tdls_options = wmi_tdls->tdls_options;
  677. cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window;
  678. cmd->tdls_peer_traffic_response_timeout_ms =
  679. wmi_tdls->peer_traffic_response_timeout;
  680. cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask;
  681. cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time;
  682. cmd->tdls_puapsd_rx_frame_threshold =
  683. wmi_tdls->puapsd_rx_frame_threshold;
  684. cmd->teardown_notification_ms =
  685. wmi_tdls->teardown_notification_ms;
  686. cmd->tdls_peer_kickout_threshold =
  687. wmi_tdls->tdls_peer_kickout_threshold;
  688. WMI_LOGD("%s: tdls_state: %d, state: %d, "
  689. "notification_interval_ms: %d, "
  690. "tx_discovery_threshold: %d, "
  691. "tx_teardown_threshold: %d, "
  692. "rssi_teardown_threshold: %d, "
  693. "rssi_delta: %d, "
  694. "tdls_options: 0x%x, "
  695. "tdls_peer_traffic_ind_window: %d, "
  696. "tdls_peer_traffic_response_timeout: %d, "
  697. "tdls_puapsd_mask: 0x%x, "
  698. "tdls_puapsd_inactivity_time: %d, "
  699. "tdls_puapsd_rx_frame_threshold: %d, "
  700. "teardown_notification_ms: %d, "
  701. "tdls_peer_kickout_threshold: %d",
  702. __func__, tdls_state, cmd->state,
  703. cmd->notification_interval_ms,
  704. cmd->tx_discovery_threshold,
  705. cmd->tx_teardown_threshold,
  706. cmd->rssi_teardown_threshold,
  707. cmd->rssi_delta,
  708. cmd->tdls_options,
  709. cmd->tdls_peer_traffic_ind_window,
  710. cmd->tdls_peer_traffic_response_timeout_ms,
  711. cmd->tdls_puapsd_mask,
  712. cmd->tdls_puapsd_inactivity_time_ms,
  713. cmd->tdls_puapsd_rx_frame_threshold,
  714. cmd->teardown_notification_ms,
  715. cmd->tdls_peer_kickout_threshold);
  716. wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0);
  717. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  718. WMI_TDLS_SET_STATE_CMDID)) {
  719. WMI_LOGP("%s: failed to send tdls set state command", __func__);
  720. wmi_buf_free(wmi_buf);
  721. return QDF_STATUS_E_FAILURE;
  722. }
  723. WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id);
  724. return QDF_STATUS_SUCCESS;
  725. }
  726. /**
  727. * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
  728. * @wmi_handle: wmi handle
  729. * @peerStateParams: TDLS peer state params
  730. *
  731. * Return: QDF_STATUS_SUCCESS for success or error code
  732. */
  733. static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
  734. struct tdls_peer_state_params *peerStateParams,
  735. uint32_t *ch_mhz)
  736. {
  737. wmi_tdls_peer_update_cmd_fixed_param *cmd;
  738. wmi_tdls_peer_capabilities *peer_cap;
  739. wmi_channel *chan_info;
  740. wmi_buf_t wmi_buf;
  741. uint8_t *buf_ptr;
  742. uint32_t i;
  743. int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
  744. sizeof(wmi_tdls_peer_capabilities);
  745. len += WMI_TLV_HDR_SIZE +
  746. sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
  747. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  748. if (!wmi_buf) {
  749. return QDF_STATUS_E_FAILURE;
  750. }
  751. buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
  752. cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
  753. WMITLV_SET_HDR(&cmd->tlv_header,
  754. WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
  755. WMITLV_GET_STRUCT_TLVLEN
  756. (wmi_tdls_peer_update_cmd_fixed_param));
  757. cmd->vdev_id = peerStateParams->vdevId;
  758. WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr,
  759. &cmd->peer_macaddr);
  760. cmd->peer_state = peerStateParams->peerState;
  761. WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, "
  762. "peer_macaddr.mac_addr31to0: 0x%x, "
  763. "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
  764. __func__, cmd->vdev_id, peerStateParams->peerMacAddr,
  765. cmd->peer_macaddr.mac_addr31to0,
  766. cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
  767. buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
  768. peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
  769. WMITLV_SET_HDR(&peer_cap->tlv_header,
  770. WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
  771. WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
  772. if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3)
  773. WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
  774. if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2)
  775. WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
  776. if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1)
  777. WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
  778. if (peerStateParams->peerCap.peerUapsdQueue & 0x01)
  779. WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
  780. /* Ack and More Data Ack are sent as 0, so no need to set
  781. * but fill SP
  782. */
  783. WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap,
  784. peerStateParams->peerCap.peerMaxSp);
  785. peer_cap->buff_sta_support =
  786. peerStateParams->peerCap.peerBuffStaSupport;
  787. peer_cap->off_chan_support =
  788. peerStateParams->peerCap.peerOffChanSupport;
  789. peer_cap->peer_curr_operclass =
  790. peerStateParams->peerCap.peerCurrOperClass;
  791. /* self curr operclass is not being used and so pass op class for
  792. * preferred off chan in it.
  793. */
  794. peer_cap->self_curr_operclass =
  795. peerStateParams->peerCap.opClassForPrefOffChan;
  796. peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen;
  797. peer_cap->peer_operclass_len =
  798. peerStateParams->peerCap.peerOperClassLen;
  799. WMI_LOGD("%s: peer_operclass_len: %d",
  800. __func__, peer_cap->peer_operclass_len);
  801. for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
  802. peer_cap->peer_operclass[i] =
  803. peerStateParams->peerCap.peerOperClass[i];
  804. WMI_LOGD("%s: peer_operclass[%d]: %d",
  805. __func__, i, peer_cap->peer_operclass[i]);
  806. }
  807. peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder;
  808. peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum;
  809. peer_cap->pref_offchan_bw =
  810. peerStateParams->peerCap.prefOffChanBandwidth;
  811. WMI_LOGD
  812. ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
  813. "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
  814. "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
  815. " %d, pref_offchan_bw: %d",
  816. __func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
  817. peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
  818. peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
  819. peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
  820. peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw);
  821. /* next fill variable size array of peer chan info */
  822. buf_ptr += sizeof(wmi_tdls_peer_capabilities);
  823. WMITLV_SET_HDR(buf_ptr,
  824. WMITLV_TAG_ARRAY_STRUC,
  825. sizeof(wmi_channel) *
  826. peerStateParams->peerCap.peerChanLen);
  827. chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
  828. for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
  829. WMITLV_SET_HDR(&chan_info->tlv_header,
  830. WMITLV_TAG_STRUC_wmi_channel,
  831. WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
  832. chan_info->mhz = ch_mhz[i];
  833. chan_info->band_center_freq1 = chan_info->mhz;
  834. chan_info->band_center_freq2 = 0;
  835. WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
  836. if (peerStateParams->peerCap.peerChan[i].dfsSet) {
  837. WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
  838. WMI_LOGI("chan[%d] DFS[%d]\n",
  839. peerStateParams->peerCap.peerChan[i].chanId,
  840. peerStateParams->peerCap.peerChan[i].dfsSet);
  841. }
  842. if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
  843. WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
  844. else
  845. WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
  846. WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
  847. peerStateParams->peerCap.
  848. peerChan[i].pwr);
  849. WMI_SET_CHANNEL_REG_POWER(chan_info,
  850. peerStateParams->peerCap.peerChan[i].
  851. pwr);
  852. WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
  853. peerStateParams->peerCap.peerChan[i].pwr);
  854. chan_info++;
  855. }
  856. wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0);
  857. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  858. WMI_TDLS_PEER_UPDATE_CMDID)) {
  859. WMI_LOGE("%s: failed to send tdls peer update state command",
  860. __func__);
  861. wmi_buf_free(wmi_buf);
  862. return QDF_STATUS_E_FAILURE;
  863. }
  864. return QDF_STATUS_SUCCESS;
  865. }
  866. /**
  867. * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
  868. * @wmi_handle: wmi handle
  869. * @param evt_buf: pointer to event buffer
  870. * @param param: Pointer to hold vdev tdls param
  871. *
  872. * Return: QDF_STATUS_SUCCESS for success or error code
  873. */
  874. static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
  875. void *evt_buf, struct tdls_event_info *param)
  876. {
  877. WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
  878. wmi_tdls_peer_event_fixed_param *evt;
  879. param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
  880. if (!param_buf) {
  881. WMI_LOGE("%s: NULL param_buf", __func__);
  882. return QDF_STATUS_E_NULL_VALUE;
  883. }
  884. evt = param_buf->fixed_param;
  885. qdf_mem_zero(param, sizeof(*param));
  886. param->vdev_id = evt->vdev_id;
  887. WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
  888. param->peermac.bytes);
  889. switch (evt->peer_status) {
  890. case WMI_TDLS_SHOULD_DISCOVER:
  891. param->message_type = TDLS_SHOULD_DISCOVER;
  892. break;
  893. case WMI_TDLS_SHOULD_TEARDOWN:
  894. param->message_type = TDLS_SHOULD_TEARDOWN;
  895. break;
  896. case WMI_TDLS_PEER_DISCONNECTED:
  897. param->message_type = TDLS_PEER_DISCONNECTED;
  898. break;
  899. case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
  900. param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
  901. break;
  902. default:
  903. WMI_LOGE("%s: Discarding unknown tdls event %d from target",
  904. __func__, evt->peer_status);
  905. return QDF_STATUS_E_INVAL;
  906. };
  907. switch (evt->peer_reason) {
  908. case WMI_TDLS_TEARDOWN_REASON_TX:
  909. param->peer_reason = TDLS_TEARDOWN_TX;
  910. break;
  911. case WMI_TDLS_TEARDOWN_REASON_RSSI:
  912. param->peer_reason = TDLS_TEARDOWN_RSSI;
  913. break;
  914. case WMI_TDLS_TEARDOWN_REASON_SCAN:
  915. param->peer_reason = TDLS_TEARDOWN_SCAN;
  916. break;
  917. case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
  918. param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
  919. break;
  920. case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
  921. param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
  922. break;
  923. case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
  924. param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
  925. break;
  926. case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
  927. param->peer_reason = TDLS_TEARDOWN_NO_RSP;
  928. break;
  929. case WMI_TDLS_ENTER_BUF_STA:
  930. param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
  931. break;
  932. case WMI_TDLS_EXIT_BUF_STA:
  933. param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
  934. break;
  935. case WMI_TDLS_ENTER_BT_BUSY_MODE:
  936. param->peer_reason = TDLS_ENTER_BT_BUSY;
  937. break;
  938. case WMI_TDLS_EXIT_BT_BUSY_MODE:
  939. param->peer_reason = TDLS_EXIT_BT_BUSY;
  940. break;
  941. case WMI_TDLS_SCAN_STARTED_EVENT:
  942. param->peer_reason = TDLS_SCAN_STARTED;
  943. break;
  944. case WMI_TDLS_SCAN_COMPLETED_EVENT:
  945. param->peer_reason = TDLS_SCAN_COMPLETED;
  946. break;
  947. default:
  948. WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
  949. __func__, evt->peer_reason, evt->peer_status);
  950. return QDF_STATUS_E_INVAL;
  951. };
  952. WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
  953. __func__, param->peermac.bytes, param->message_type,
  954. param->peer_reason, param->vdev_id);
  955. return QDF_STATUS_SUCCESS;
  956. }
  957. void wmi_tdls_attach_tlv(struct wmi_unified *wmi_handle)
  958. {
  959. struct wmi_ops *ops = wmi_handle->ops;
  960. ops->send_set_tdls_offchan_mode_cmd =
  961. send_set_tdls_offchan_mode_cmd_tlv;
  962. ops->send_update_fw_tdls_state_cmd =
  963. send_update_fw_tdls_state_cmd_tlv;
  964. ops->send_update_tdls_peer_state_cmd =
  965. send_update_tdls_peer_state_cmd_tlv;
  966. ops->extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv;
  967. }
  968. #endif /* CONVERGED_TDLS_ENABLE */
  969. /*
  970. * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
  971. * @wmi_handle: Pointer to WMi handle
  972. * @ie_data: Pointer for ie data
  973. *
  974. * This function sends IE information to firmware
  975. *
  976. * Return: QDF_STATUS_SUCCESS for success otherwise failure
  977. *
  978. */
  979. static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
  980. struct vdev_ie_info_param *ie_info)
  981. {
  982. wmi_vdev_set_ie_cmd_fixed_param *cmd;
  983. wmi_buf_t buf;
  984. uint8_t *buf_ptr;
  985. uint32_t len, ie_len_aligned;
  986. QDF_STATUS ret;
  987. ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
  988. /* Allocate memory for the WMI command */
  989. len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
  990. buf = wmi_buf_alloc(wmi_handle, len);
  991. if (!buf) {
  992. return QDF_STATUS_E_NOMEM;
  993. }
  994. buf_ptr = wmi_buf_data(buf);
  995. qdf_mem_zero(buf_ptr, len);
  996. /* Populate the WMI command */
  997. cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
  998. WMITLV_SET_HDR(&cmd->tlv_header,
  999. WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
  1000. WMITLV_GET_STRUCT_TLVLEN(
  1001. wmi_vdev_set_ie_cmd_fixed_param));
  1002. cmd->vdev_id = ie_info->vdev_id;
  1003. cmd->ie_id = ie_info->ie_id;
  1004. cmd->ie_len = ie_info->length;
  1005. cmd->band = ie_info->band;
  1006. WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
  1007. ie_info->length, ie_info->vdev_id);
  1008. buf_ptr += sizeof(*cmd);
  1009. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
  1010. buf_ptr += WMI_TLV_HDR_SIZE;
  1011. qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
  1012. wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0);
  1013. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  1014. WMI_VDEV_SET_IE_CMDID);
  1015. if (QDF_IS_STATUS_ERROR(ret)) {
  1016. WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
  1017. wmi_buf_free(buf);
  1018. }
  1019. return ret;
  1020. }
  1021. /**
  1022. * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
  1023. * @wmi_handle: wmi handle
  1024. * @custom_addr: base mac address
  1025. *
  1026. * Return: QDF_STATUS_SUCCESS for success or error code
  1027. */
  1028. static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
  1029. uint8_t *custom_addr)
  1030. {
  1031. wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
  1032. wmi_buf_t buf;
  1033. int err;
  1034. buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
  1035. if (!buf) {
  1036. return QDF_STATUS_E_NOMEM;
  1037. }
  1038. cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
  1039. qdf_mem_zero(cmd, sizeof(*cmd));
  1040. WMITLV_SET_HDR(&cmd->tlv_header,
  1041. WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
  1042. WMITLV_GET_STRUCT_TLVLEN
  1043. (wmi_pdev_set_base_macaddr_cmd_fixed_param));
  1044. WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
  1045. cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
  1046. WMI_HOST_PDEV_ID_SOC);
  1047. wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0);
  1048. err = wmi_unified_cmd_send(wmi_handle, buf,
  1049. sizeof(*cmd),
  1050. WMI_PDEV_SET_BASE_MACADDR_CMDID);
  1051. if (err) {
  1052. WMI_LOGE("Failed to send set_base_macaddr cmd");
  1053. wmi_buf_free(buf);
  1054. return QDF_STATUS_E_FAILURE;
  1055. }
  1056. return 0;
  1057. }
  1058. #ifdef WLAN_FEATURE_DISA
  1059. /**
  1060. * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw
  1061. * @wmi_handle: wmi handle
  1062. * @params: encrypt/decrypt params
  1063. *
  1064. * Return: QDF_STATUS_SUCCESS for success or error code
  1065. */
  1066. static
  1067. QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle,
  1068. struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params)
  1069. {
  1070. wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd;
  1071. wmi_buf_t wmi_buf;
  1072. uint8_t *buf_ptr;
  1073. QDF_STATUS ret;
  1074. uint32_t len;
  1075. WMI_LOGD(FL("Send encrypt decrypt cmd"));
  1076. len = sizeof(*cmd) +
  1077. roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) +
  1078. WMI_TLV_HDR_SIZE;
  1079. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  1080. if (!wmi_buf) {
  1081. return QDF_STATUS_E_NOMEM;
  1082. }
  1083. buf_ptr = wmi_buf_data(wmi_buf);
  1084. cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr;
  1085. WMITLV_SET_HDR(&cmd->tlv_header,
  1086. WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param,
  1087. WMITLV_GET_STRUCT_TLVLEN(
  1088. wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param));
  1089. cmd->vdev_id = encrypt_decrypt_params->vdev_id;
  1090. cmd->key_flag = encrypt_decrypt_params->key_flag;
  1091. cmd->key_idx = encrypt_decrypt_params->key_idx;
  1092. cmd->key_cipher = encrypt_decrypt_params->key_cipher;
  1093. cmd->key_len = encrypt_decrypt_params->key_len;
  1094. cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len;
  1095. cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len;
  1096. qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data,
  1097. encrypt_decrypt_params->key_len);
  1098. qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header,
  1099. MAX_MAC_HEADER_LEN);
  1100. cmd->data_len = encrypt_decrypt_params->data_len;
  1101. if (cmd->data_len) {
  1102. buf_ptr += sizeof(*cmd);
  1103. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
  1104. roundup(encrypt_decrypt_params->data_len,
  1105. sizeof(uint32_t)));
  1106. buf_ptr += WMI_TLV_HDR_SIZE;
  1107. qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data,
  1108. encrypt_decrypt_params->data_len);
  1109. }
  1110. /* This conversion is to facilitate data to FW in little endian */
  1111. cmd->pn[5] = encrypt_decrypt_params->pn[0];
  1112. cmd->pn[4] = encrypt_decrypt_params->pn[1];
  1113. cmd->pn[3] = encrypt_decrypt_params->pn[2];
  1114. cmd->pn[2] = encrypt_decrypt_params->pn[3];
  1115. cmd->pn[1] = encrypt_decrypt_params->pn[4];
  1116. cmd->pn[0] = encrypt_decrypt_params->pn[5];
  1117. wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0);
  1118. ret = wmi_unified_cmd_send(wmi_handle,
  1119. wmi_buf, len,
  1120. WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID);
  1121. if (QDF_IS_STATUS_ERROR(ret)) {
  1122. WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret);
  1123. wmi_buf_free(wmi_buf);
  1124. }
  1125. return ret;
  1126. }
  1127. /**
  1128. * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp
  1129. * params from event
  1130. * @wmi_handle: wmi handle
  1131. * @evt_buf: pointer to event buffer
  1132. * @resp: Pointer to hold resp parameters
  1133. *
  1134. * Return: QDF_STATUS_SUCCESS for success or error code
  1135. */
  1136. static
  1137. QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle,
  1138. void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp)
  1139. {
  1140. WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
  1141. wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
  1142. param_buf = evt_buf;
  1143. if (!param_buf) {
  1144. WMI_LOGE("encrypt decrypt resp evt_buf is NULL");
  1145. return QDF_STATUS_E_INVAL;
  1146. }
  1147. data_event = param_buf->fixed_param;
  1148. resp->vdev_id = data_event->vdev_id;
  1149. resp->status = data_event->status;
  1150. if ((data_event->data_length > param_buf->num_enc80211_frame) ||
  1151. (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE -
  1152. sizeof(*data_event))) {
  1153. WMI_LOGE("FW msg data_len %d more than TLV hdr %d",
  1154. data_event->data_length,
  1155. param_buf->num_enc80211_frame);
  1156. return QDF_STATUS_E_INVAL;
  1157. }
  1158. resp->data_len = data_event->data_length;
  1159. if (resp->data_len)
  1160. resp->data = (uint8_t *)param_buf->enc80211_frame;
  1161. return QDF_STATUS_SUCCESS;
  1162. }
  1163. void wmi_disa_attach_tlv(struct wmi_unified *wmi_handle)
  1164. {
  1165. struct wmi_ops *ops = wmi_handle->ops;
  1166. ops->send_encrypt_decrypt_send_cmd =
  1167. send_encrypt_decrypt_send_cmd_tlv;
  1168. ops->extract_encrypt_decrypt_resp_event =
  1169. extract_encrypt_decrypt_resp_event_tlv;
  1170. }
  1171. #endif /* WLAN_FEATURE_DISA */
  1172. /**
  1173. * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
  1174. * @wmi_handle: wmi handle
  1175. * @params: sar limit params
  1176. *
  1177. * Return: QDF_STATUS_SUCCESS for success or error code
  1178. */
  1179. static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
  1180. struct sar_limit_cmd_params *sar_limit_params)
  1181. {
  1182. wmi_buf_t buf;
  1183. QDF_STATUS qdf_status;
  1184. wmi_sar_limits_cmd_fixed_param *cmd;
  1185. int i;
  1186. uint8_t *buf_ptr;
  1187. wmi_sar_limit_cmd_row *wmi_sar_rows_list;
  1188. struct sar_limit_cmd_row *sar_rows_list;
  1189. uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
  1190. len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
  1191. buf = wmi_buf_alloc(wmi_handle, len);
  1192. if (!buf) {
  1193. qdf_status = QDF_STATUS_E_NOMEM;
  1194. goto end;
  1195. }
  1196. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1197. cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
  1198. WMITLV_SET_HDR(&cmd->tlv_header,
  1199. WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
  1200. WMITLV_GET_STRUCT_TLVLEN
  1201. (wmi_sar_limits_cmd_fixed_param));
  1202. cmd->sar_enable = sar_limit_params->sar_enable;
  1203. cmd->commit_limits = sar_limit_params->commit_limits;
  1204. cmd->num_limit_rows = sar_limit_params->num_limit_rows;
  1205. WMI_LOGD("no of sar rows = %d, len = %d",
  1206. sar_limit_params->num_limit_rows, len);
  1207. buf_ptr += sizeof(*cmd);
  1208. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1209. sizeof(wmi_sar_limit_cmd_row) *
  1210. sar_limit_params->num_limit_rows);
  1211. if (cmd->num_limit_rows == 0)
  1212. goto send_sar_limits;
  1213. wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
  1214. (buf_ptr + WMI_TLV_HDR_SIZE);
  1215. sar_rows_list = sar_limit_params->sar_limit_row_list;
  1216. for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
  1217. WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
  1218. WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
  1219. WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
  1220. wmi_sar_rows_list->band_id = sar_rows_list->band_id;
  1221. wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
  1222. wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
  1223. wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
  1224. wmi_sar_rows_list->validity_bitmap =
  1225. sar_rows_list->validity_bitmap;
  1226. WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
  1227. i, wmi_sar_rows_list->band_id,
  1228. wmi_sar_rows_list->chain_id,
  1229. wmi_sar_rows_list->mod_id,
  1230. wmi_sar_rows_list->limit_value,
  1231. wmi_sar_rows_list->validity_bitmap);
  1232. sar_rows_list++;
  1233. wmi_sar_rows_list++;
  1234. }
  1235. send_sar_limits:
  1236. wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0);
  1237. qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
  1238. WMI_SAR_LIMITS_CMDID);
  1239. if (QDF_IS_STATUS_ERROR(qdf_status)) {
  1240. WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
  1241. wmi_buf_free(buf);
  1242. }
  1243. end:
  1244. return qdf_status;
  1245. }
  1246. static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
  1247. {
  1248. wmi_sar_get_limits_cmd_fixed_param *cmd;
  1249. wmi_buf_t wmi_buf;
  1250. uint32_t len;
  1251. QDF_STATUS status;
  1252. WMI_LOGD(FL("Enter"));
  1253. len = sizeof(*cmd);
  1254. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  1255. if (!wmi_buf) {
  1256. return QDF_STATUS_E_NOMEM;
  1257. }
  1258. cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
  1259. WMITLV_SET_HDR(&cmd->tlv_header,
  1260. WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
  1261. WMITLV_GET_STRUCT_TLVLEN
  1262. (wmi_sar_get_limits_cmd_fixed_param));
  1263. cmd->reserved = 0;
  1264. wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0);
  1265. status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  1266. WMI_SAR_GET_LIMITS_CMDID);
  1267. if (QDF_IS_STATUS_ERROR(status)) {
  1268. WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
  1269. wmi_buf_free(wmi_buf);
  1270. }
  1271. WMI_LOGD(FL("Exit"));
  1272. return status;
  1273. }
  1274. /**
  1275. * wmi_sar2_result_string() - return string conversion of sar2 result
  1276. * @result: sar2 result value
  1277. *
  1278. * This utility function helps log string conversion of sar2 result.
  1279. *
  1280. * Return: string conversion of sar 2 result, if match found;
  1281. * "Unknown response" otherwise.
  1282. */
  1283. static const char *wmi_sar2_result_string(uint32_t result)
  1284. {
  1285. switch (result) {
  1286. CASE_RETURN_STRING(WMI_SAR2_SUCCESS);
  1287. CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX);
  1288. CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX);
  1289. CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR);
  1290. CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE);
  1291. default:
  1292. return "Unknown response";
  1293. }
  1294. }
  1295. /**
  1296. * extract_sar2_result_event_tlv() - process sar response event from FW.
  1297. * @handle: wma handle
  1298. * @event: event buffer
  1299. * @len: buffer length
  1300. *
  1301. * Return: 0 for success or error code
  1302. */
  1303. static QDF_STATUS extract_sar2_result_event_tlv(void *handle,
  1304. uint8_t *event,
  1305. uint32_t len)
  1306. {
  1307. wmi_sar2_result_event_fixed_param *sar2_fixed_param;
  1308. WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf =
  1309. (WMI_SAR2_RESULT_EVENTID_param_tlvs *)event;
  1310. if (!param_buf) {
  1311. WMI_LOGI("Invalid sar2 result event buffer");
  1312. return QDF_STATUS_E_INVAL;
  1313. }
  1314. sar2_fixed_param = param_buf->fixed_param;
  1315. if (!sar2_fixed_param) {
  1316. WMI_LOGI("Invalid sar2 result event fixed param buffer");
  1317. return QDF_STATUS_E_INVAL;
  1318. }
  1319. WMI_LOGI("SAR2 result: %s",
  1320. wmi_sar2_result_string(sar2_fixed_param->result));
  1321. return QDF_STATUS_SUCCESS;
  1322. }
  1323. static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
  1324. uint8_t *evt_buf,
  1325. struct sar_limit_event *event)
  1326. {
  1327. wmi_sar_get_limits_event_fixed_param *fixed_param;
  1328. WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
  1329. wmi_sar_get_limit_event_row *row_in;
  1330. struct sar_limit_event_row *row_out;
  1331. uint32_t row;
  1332. if (!evt_buf) {
  1333. WMI_LOGE(FL("input event is NULL"));
  1334. return QDF_STATUS_E_INVAL;
  1335. }
  1336. if (!event) {
  1337. WMI_LOGE(FL("output event is NULL"));
  1338. return QDF_STATUS_E_INVAL;
  1339. }
  1340. param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
  1341. fixed_param = param_buf->fixed_param;
  1342. if (!fixed_param) {
  1343. WMI_LOGE(FL("Invalid fixed param"));
  1344. return QDF_STATUS_E_INVAL;
  1345. }
  1346. event->sar_enable = fixed_param->sar_enable;
  1347. event->num_limit_rows = fixed_param->num_limit_rows;
  1348. if (event->num_limit_rows > param_buf->num_sar_get_limits) {
  1349. WMI_LOGE(FL("Num rows %d exceeds sar_get_limits rows len %d"),
  1350. event->num_limit_rows, param_buf->num_sar_get_limits);
  1351. return QDF_STATUS_E_INVAL;
  1352. }
  1353. if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
  1354. QDF_ASSERT(0);
  1355. WMI_LOGE(FL("Num rows %d exceeds max of %d"),
  1356. event->num_limit_rows,
  1357. MAX_SAR_LIMIT_ROWS_SUPPORTED);
  1358. event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
  1359. }
  1360. row_in = param_buf->sar_get_limits;
  1361. if (!row_in) {
  1362. WMI_LOGD("sar_get_limits is NULL");
  1363. } else {
  1364. row_out = &event->sar_limit_row[0];
  1365. for (row = 0; row < event->num_limit_rows; row++) {
  1366. row_out->band_id = row_in->band_id;
  1367. row_out->chain_id = row_in->chain_id;
  1368. row_out->mod_id = row_in->mod_id;
  1369. row_out->limit_value = row_in->limit_value;
  1370. row_out++;
  1371. row_in++;
  1372. }
  1373. }
  1374. return QDF_STATUS_SUCCESS;
  1375. }
  1376. /**
  1377. * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
  1378. * @wmi_handle: wmi handler
  1379. * @pmk_info: pointer to PMK cache entry
  1380. * @vdev_id: vdev id
  1381. *
  1382. * Return: 0 for success and non zero for failure
  1383. */
  1384. static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
  1385. struct wmi_unified_pmk_cache *pmk_info)
  1386. {
  1387. wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
  1388. wmi_buf_t buf;
  1389. QDF_STATUS status;
  1390. uint8_t *buf_ptr;
  1391. wmi_pmk_cache *pmksa;
  1392. uint32_t len = sizeof(*cmd);
  1393. if (pmk_info->pmk_len)
  1394. len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
  1395. buf = wmi_buf_alloc(wmi_handle, len);
  1396. if (!buf) {
  1397. return QDF_STATUS_E_NOMEM;
  1398. }
  1399. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1400. cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
  1401. WMITLV_SET_HDR(&cmd->tlv_header,
  1402. WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
  1403. WMITLV_GET_STRUCT_TLVLEN(
  1404. wmi_pdev_update_pmk_cache_cmd_fixed_param));
  1405. cmd->vdev_id = pmk_info->session_id;
  1406. /* If pmk_info->pmk_len is 0, this is a flush request */
  1407. if (!pmk_info->pmk_len) {
  1408. cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
  1409. cmd->num_cache = 0;
  1410. goto send_cmd;
  1411. }
  1412. cmd->num_cache = 1;
  1413. buf_ptr += sizeof(*cmd);
  1414. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1415. sizeof(*pmksa));
  1416. buf_ptr += WMI_TLV_HDR_SIZE;
  1417. pmksa = (wmi_pmk_cache *)buf_ptr;
  1418. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
  1419. WMITLV_GET_STRUCT_TLVLEN
  1420. (wmi_pmk_cache));
  1421. pmksa->pmk_len = pmk_info->pmk_len;
  1422. qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
  1423. pmksa->pmkid_len = pmk_info->pmkid_len;
  1424. qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
  1425. qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
  1426. pmksa->ssid.ssid_len = pmk_info->ssid.length;
  1427. qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid),
  1428. pmksa->ssid.ssid_len);
  1429. pmksa->cache_id = pmk_info->cache_id;
  1430. pmksa->cat_flag = pmk_info->cat_flag;
  1431. pmksa->action_flag = pmk_info->action_flag;
  1432. send_cmd:
  1433. wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0);
  1434. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  1435. WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
  1436. if (status != QDF_STATUS_SUCCESS) {
  1437. WMI_LOGE("%s: failed to send set del pmkid cache command %d",
  1438. __func__, status);
  1439. wmi_buf_free(buf);
  1440. }
  1441. return status;
  1442. }
  1443. /**
  1444. * send_del_ts_cmd_tlv() - send DELTS request to fw
  1445. * @wmi_handle: wmi handle
  1446. * @msg: delts params
  1447. *
  1448. * Return: CDF status
  1449. */
  1450. static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
  1451. uint8_t ac)
  1452. {
  1453. wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
  1454. wmi_buf_t buf;
  1455. int32_t len = sizeof(*cmd);
  1456. buf = wmi_buf_alloc(wmi_handle, len);
  1457. if (!buf) {
  1458. return QDF_STATUS_E_NOMEM;
  1459. }
  1460. cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
  1461. WMITLV_SET_HDR(&cmd->tlv_header,
  1462. WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
  1463. WMITLV_GET_STRUCT_TLVLEN
  1464. (wmi_vdev_wmm_delts_cmd_fixed_param));
  1465. cmd->vdev_id = vdev_id;
  1466. cmd->ac = ac;
  1467. WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
  1468. cmd->vdev_id, cmd->ac, __func__, __LINE__);
  1469. wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0);
  1470. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1471. WMI_VDEV_WMM_DELTS_CMDID)) {
  1472. WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
  1473. wmi_buf_free(buf);
  1474. return QDF_STATUS_E_FAILURE;
  1475. }
  1476. return QDF_STATUS_SUCCESS;
  1477. }
  1478. /**
  1479. * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
  1480. * @wmi_handle: handle to wmi
  1481. * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
  1482. *
  1483. * A function to handle WMI_AGGR_QOS_REQ. This will send out
  1484. * ADD_TS requestes to firmware in loop for all the ACs with
  1485. * active flow.
  1486. *
  1487. * Return: CDF status
  1488. */
  1489. static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
  1490. struct aggr_add_ts_param *aggr_qos_rsp_msg)
  1491. {
  1492. int i = 0;
  1493. wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
  1494. wmi_buf_t buf;
  1495. int32_t len = sizeof(*cmd);
  1496. for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
  1497. /* if flow in this AC is active */
  1498. if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
  1499. /*
  1500. * as per implementation of wma_add_ts_req() we
  1501. * are not waiting any response from firmware so
  1502. * apart from sending ADDTS to firmware just send
  1503. * success to upper layers
  1504. */
  1505. aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
  1506. buf = wmi_buf_alloc(wmi_handle, len);
  1507. if (!buf) {
  1508. return QDF_STATUS_E_NOMEM;
  1509. }
  1510. cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
  1511. wmi_buf_data(buf);
  1512. WMITLV_SET_HDR(&cmd->tlv_header,
  1513. WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
  1514. WMITLV_GET_STRUCT_TLVLEN
  1515. (wmi_vdev_wmm_addts_cmd_fixed_param));
  1516. cmd->vdev_id = aggr_qos_rsp_msg->vdev_id;
  1517. cmd->ac =
  1518. WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
  1519. traffic.userPrio);
  1520. cmd->medium_time_us =
  1521. aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
  1522. cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
  1523. WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
  1524. __func__, __LINE__, cmd->vdev_id, cmd->ac,
  1525. cmd->medium_time_us, cmd->downgrade_type);
  1526. wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
  1527. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1528. WMI_VDEV_WMM_ADDTS_CMDID)) {
  1529. WMI_LOGP("%s: Failed to send vdev ADDTS command",
  1530. __func__);
  1531. aggr_qos_rsp_msg->status[i] =
  1532. QDF_STATUS_E_FAILURE;
  1533. wmi_buf_free(buf);
  1534. return QDF_STATUS_E_FAILURE;
  1535. }
  1536. }
  1537. }
  1538. return QDF_STATUS_SUCCESS;
  1539. }
  1540. /**
  1541. * send_add_ts_cmd_tlv() - send ADDTS request to fw
  1542. * @wmi_handle: wmi handle
  1543. * @msg: ADDTS params
  1544. *
  1545. * Return: CDF status
  1546. */
  1547. static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
  1548. struct add_ts_param *msg)
  1549. {
  1550. wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
  1551. wmi_buf_t buf;
  1552. int32_t len = sizeof(*cmd);
  1553. msg->status = QDF_STATUS_SUCCESS;
  1554. buf = wmi_buf_alloc(wmi_handle, len);
  1555. if (!buf) {
  1556. return QDF_STATUS_E_NOMEM;
  1557. }
  1558. cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
  1559. WMITLV_SET_HDR(&cmd->tlv_header,
  1560. WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
  1561. WMITLV_GET_STRUCT_TLVLEN
  1562. (wmi_vdev_wmm_addts_cmd_fixed_param));
  1563. cmd->vdev_id = msg->sme_session_id;
  1564. cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
  1565. cmd->medium_time_us = msg->tspec.mediumTime * 32;
  1566. cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
  1567. WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
  1568. cmd->vdev_id, cmd->ac, cmd->medium_time_us,
  1569. cmd->downgrade_type, __func__, __LINE__);
  1570. wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
  1571. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1572. WMI_VDEV_WMM_ADDTS_CMDID)) {
  1573. WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
  1574. msg->status = QDF_STATUS_E_FAILURE;
  1575. wmi_buf_free(buf);
  1576. return QDF_STATUS_E_FAILURE;
  1577. }
  1578. return QDF_STATUS_SUCCESS;
  1579. }
  1580. /**
  1581. * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn
  1582. * @wmi_handle: wmi handle
  1583. * @pAddPeriodicTxPtrnParams: tx ptrn params
  1584. *
  1585. * Retrun: CDF status
  1586. */
  1587. static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
  1588. struct periodic_tx_pattern *
  1589. pAddPeriodicTxPtrnParams,
  1590. uint8_t vdev_id)
  1591. {
  1592. WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
  1593. wmi_buf_t wmi_buf;
  1594. uint32_t len;
  1595. uint8_t *buf_ptr;
  1596. uint32_t ptrn_len, ptrn_len_aligned;
  1597. int j;
  1598. ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize;
  1599. ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
  1600. len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
  1601. WMI_TLV_HDR_SIZE + ptrn_len_aligned;
  1602. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  1603. if (!wmi_buf) {
  1604. return QDF_STATUS_E_NOMEM;
  1605. }
  1606. buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
  1607. cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
  1608. WMITLV_SET_HDR(&cmd->tlv_header,
  1609. WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
  1610. WMITLV_GET_STRUCT_TLVLEN
  1611. (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
  1612. /* Pass the pattern id to delete for the corresponding vdev id */
  1613. cmd->vdev_id = vdev_id;
  1614. cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId;
  1615. cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
  1616. cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize;
  1617. /* Pattern info */
  1618. buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
  1619. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
  1620. buf_ptr += WMI_TLV_HDR_SIZE;
  1621. qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
  1622. for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++)
  1623. WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
  1624. WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
  1625. __func__, cmd->pattern_id, cmd->vdev_id);
  1626. wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
  1627. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  1628. WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
  1629. WMI_LOGE("%s: failed to add pattern set state command",
  1630. __func__);
  1631. wmi_buf_free(wmi_buf);
  1632. return QDF_STATUS_E_FAILURE;
  1633. }
  1634. return QDF_STATUS_SUCCESS;
  1635. }
  1636. /**
  1637. * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn
  1638. * @wmi_handle: wmi handle
  1639. * @vdev_id: vdev id
  1640. * @pattern_id: pattern id
  1641. *
  1642. * Retrun: CDF status
  1643. */
  1644. static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
  1645. uint8_t vdev_id,
  1646. uint8_t pattern_id)
  1647. {
  1648. WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
  1649. wmi_buf_t wmi_buf;
  1650. uint32_t len =
  1651. sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
  1652. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  1653. if (!wmi_buf) {
  1654. return QDF_STATUS_E_NOMEM;
  1655. }
  1656. cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
  1657. wmi_buf_data(wmi_buf);
  1658. WMITLV_SET_HDR(&cmd->tlv_header,
  1659. WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
  1660. WMITLV_GET_STRUCT_TLVLEN
  1661. (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
  1662. /* Pass the pattern id to delete for the corresponding vdev id */
  1663. cmd->vdev_id = vdev_id;
  1664. cmd->pattern_id = pattern_id;
  1665. WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
  1666. __func__, cmd->pattern_id, cmd->vdev_id);
  1667. wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
  1668. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  1669. WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
  1670. WMI_LOGE("%s: failed to send del pattern command", __func__);
  1671. wmi_buf_free(wmi_buf);
  1672. return QDF_STATUS_E_FAILURE;
  1673. }
  1674. return QDF_STATUS_SUCCESS;
  1675. }
  1676. /**
  1677. * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
  1678. * @wmi_handle: wmi handle
  1679. * @timer_val: auto shutdown timer value
  1680. *
  1681. * Return: CDF status
  1682. */
  1683. static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
  1684. uint32_t timer_val)
  1685. {
  1686. QDF_STATUS status;
  1687. wmi_buf_t buf = NULL;
  1688. uint8_t *buf_ptr;
  1689. wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
  1690. int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
  1691. WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
  1692. __func__, timer_val);
  1693. buf = wmi_buf_alloc(wmi_handle, len);
  1694. if (!buf) {
  1695. return QDF_STATUS_E_NOMEM;
  1696. }
  1697. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1698. wmi_auto_sh_cmd =
  1699. (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
  1700. wmi_auto_sh_cmd->timer_value = timer_val;
  1701. WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
  1702. WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
  1703. WMITLV_GET_STRUCT_TLVLEN
  1704. (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
  1705. wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0);
  1706. status = wmi_unified_cmd_send(wmi_handle, buf,
  1707. len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
  1708. if (QDF_IS_STATUS_ERROR(status)) {
  1709. WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
  1710. __func__, status);
  1711. wmi_buf_free(buf);
  1712. }
  1713. return status;
  1714. }
  1715. /**
  1716. * send_set_led_flashing_cmd_tlv() - set led flashing in fw
  1717. * @wmi_handle: wmi handle
  1718. * @flashing: flashing request
  1719. *
  1720. * Return: CDF status
  1721. */
  1722. static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
  1723. struct flashing_req_params *flashing)
  1724. {
  1725. wmi_set_led_flashing_cmd_fixed_param *cmd;
  1726. QDF_STATUS status;
  1727. wmi_buf_t buf;
  1728. uint8_t *buf_ptr;
  1729. int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
  1730. buf = wmi_buf_alloc(wmi_handle, len);
  1731. if (!buf) {
  1732. return QDF_STATUS_E_NOMEM;
  1733. }
  1734. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1735. cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
  1736. WMITLV_SET_HDR(&cmd->tlv_header,
  1737. WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
  1738. WMITLV_GET_STRUCT_TLVLEN
  1739. (wmi_set_led_flashing_cmd_fixed_param));
  1740. cmd->pattern_id = flashing->pattern_id;
  1741. cmd->led_x0 = flashing->led_x0;
  1742. cmd->led_x1 = flashing->led_x1;
  1743. wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0);
  1744. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  1745. WMI_PDEV_SET_LED_FLASHING_CMDID);
  1746. if (QDF_IS_STATUS_ERROR(status)) {
  1747. WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
  1748. " returned Error %d", __func__, status);
  1749. wmi_buf_free(buf);
  1750. }
  1751. return status;
  1752. }
  1753. /**
  1754. * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
  1755. * @wmi_handle: wmi handle
  1756. * @ch_avoid_update_req: channel avoid update params
  1757. *
  1758. * Return: CDF status
  1759. */
  1760. static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
  1761. {
  1762. QDF_STATUS status;
  1763. wmi_buf_t buf = NULL;
  1764. uint8_t *buf_ptr;
  1765. wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
  1766. int len = sizeof(wmi_chan_avoid_update_cmd_param);
  1767. buf = wmi_buf_alloc(wmi_handle, len);
  1768. if (!buf) {
  1769. return QDF_STATUS_E_NOMEM;
  1770. }
  1771. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1772. ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
  1773. WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
  1774. WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
  1775. WMITLV_GET_STRUCT_TLVLEN
  1776. (wmi_chan_avoid_update_cmd_param));
  1777. wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0);
  1778. status = wmi_unified_cmd_send(wmi_handle, buf,
  1779. len, WMI_CHAN_AVOID_UPDATE_CMDID);
  1780. if (QDF_IS_STATUS_ERROR(status)) {
  1781. WMI_LOGE("wmi_unified_cmd_send"
  1782. " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
  1783. " returned Error %d", status);
  1784. wmi_buf_free(buf);
  1785. }
  1786. return status;
  1787. }
  1788. /**
  1789. * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
  1790. * @wmi_handle: wmi handle
  1791. * @msg: PCL structure containing the PCL and the number of channels
  1792. *
  1793. * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
  1794. * firmware. The DBS Manager is the consumer of this information in the WLAN
  1795. * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
  1796. * to migrate to a new channel without host driver involvement. An example of
  1797. * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
  1798. * manage the channel selection without firmware involvement.
  1799. *
  1800. * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
  1801. * channel list. The weights corresponds to the channels sent in
  1802. * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
  1803. * weightage compared to the non PCL channels.
  1804. *
  1805. * Return: Success if the cmd is sent successfully to the firmware
  1806. */
  1807. static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
  1808. struct wmi_pcl_chan_weights *msg)
  1809. {
  1810. wmi_pdev_set_pcl_cmd_fixed_param *cmd;
  1811. wmi_buf_t buf;
  1812. uint8_t *buf_ptr;
  1813. uint32_t *cmd_args, i, len;
  1814. uint32_t chan_len;
  1815. chan_len = msg->saved_num_chan;
  1816. len = sizeof(*cmd) +
  1817. WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
  1818. buf = wmi_buf_alloc(wmi_handle, len);
  1819. if (!buf) {
  1820. return QDF_STATUS_E_NOMEM;
  1821. }
  1822. cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
  1823. buf_ptr = (uint8_t *) cmd;
  1824. WMITLV_SET_HDR(&cmd->tlv_header,
  1825. WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
  1826. WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
  1827. cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
  1828. WMI_HOST_PDEV_ID_SOC);
  1829. cmd->num_chan = chan_len;
  1830. WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan);
  1831. buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
  1832. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
  1833. (chan_len * sizeof(uint32_t)));
  1834. cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
  1835. for (i = 0; i < chan_len ; i++) {
  1836. cmd_args[i] = msg->weighed_valid_list[i];
  1837. WMI_LOGD("%s: chan:%d weight:%d", __func__,
  1838. msg->saved_chan_list[i], cmd_args[i]);
  1839. }
  1840. wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0);
  1841. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1842. WMI_PDEV_SET_PCL_CMDID)) {
  1843. WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
  1844. wmi_buf_free(buf);
  1845. return QDF_STATUS_E_FAILURE;
  1846. }
  1847. return QDF_STATUS_SUCCESS;
  1848. }
  1849. /**
  1850. * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
  1851. * @wmi_handle: wmi handle
  1852. * @msg: Structure containing the following parameters
  1853. *
  1854. * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
  1855. * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
  1856. *
  1857. * Provides notification to the WLAN firmware that host driver is requesting a
  1858. * HardWare (HW) Mode change. This command is needed to support iHelium in the
  1859. * configurations that include the Dual Band Simultaneous (DBS) feature.
  1860. *
  1861. * Return: Success if the cmd is sent successfully to the firmware
  1862. */
  1863. static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle,
  1864. uint32_t hw_mode_index)
  1865. {
  1866. wmi_pdev_set_hw_mode_cmd_fixed_param *cmd;
  1867. wmi_buf_t buf;
  1868. uint32_t len;
  1869. len = sizeof(*cmd);
  1870. buf = wmi_buf_alloc(wmi_handle, len);
  1871. if (!buf) {
  1872. return QDF_STATUS_E_NOMEM;
  1873. }
  1874. cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
  1875. WMITLV_SET_HDR(&cmd->tlv_header,
  1876. WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
  1877. WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param));
  1878. cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
  1879. WMI_HOST_PDEV_ID_SOC);
  1880. cmd->hw_mode_index = hw_mode_index;
  1881. WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
  1882. wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0);
  1883. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1884. WMI_PDEV_SET_HW_MODE_CMDID)) {
  1885. WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID",
  1886. __func__);
  1887. wmi_buf_free(buf);
  1888. return QDF_STATUS_E_FAILURE;
  1889. }
  1890. return QDF_STATUS_SUCCESS;
  1891. }
  1892. #ifdef WLAN_POLICY_MGR_ENABLE
  1893. /**
  1894. * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
  1895. * @wmi_handle: wmi handle
  1896. * @msg: Dual MAC config parameters
  1897. *
  1898. * Configures WLAN firmware with the dual MAC features
  1899. *
  1900. * Return: QDF_STATUS. 0 on success.
  1901. */
  1902. static
  1903. QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
  1904. struct policy_mgr_dual_mac_config *msg)
  1905. {
  1906. wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
  1907. wmi_buf_t buf;
  1908. uint32_t len;
  1909. len = sizeof(*cmd);
  1910. buf = wmi_buf_alloc(wmi_handle, len);
  1911. if (!buf) {
  1912. return QDF_STATUS_E_FAILURE;
  1913. }
  1914. cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
  1915. WMITLV_SET_HDR(&cmd->tlv_header,
  1916. WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
  1917. WMITLV_GET_STRUCT_TLVLEN(
  1918. wmi_pdev_set_mac_config_cmd_fixed_param));
  1919. cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
  1920. WMI_HOST_PDEV_ID_SOC);
  1921. cmd->concurrent_scan_config_bits = msg->scan_config;
  1922. cmd->fw_mode_config_bits = msg->fw_mode_config;
  1923. WMI_LOGD("%s: scan_config:%x fw_mode_config:%x",
  1924. __func__, msg->scan_config, msg->fw_mode_config);
  1925. wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0);
  1926. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1927. WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
  1928. WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
  1929. __func__);
  1930. wmi_buf_free(buf);
  1931. return QDF_STATUS_E_FAILURE;
  1932. }
  1933. return QDF_STATUS_SUCCESS;
  1934. }
  1935. void wmi_policy_mgr_attach_tlv(struct wmi_unified *wmi_handle)
  1936. {
  1937. struct wmi_ops *ops = wmi_handle->ops;
  1938. ops->send_pdev_set_dual_mac_config_cmd =
  1939. send_pdev_set_dual_mac_config_cmd_tlv;
  1940. }
  1941. #endif /* WLAN_POLICY_MGR_ENABLE */
  1942. /**
  1943. * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
  1944. * configuration params
  1945. * @wma_handle: wma handler
  1946. * @dwelltime_params: pointer to dwelltime_params
  1947. *
  1948. * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
  1949. */
  1950. static
  1951. QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
  1952. struct wmi_adaptive_dwelltime_params *dwelltime_params)
  1953. {
  1954. wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
  1955. wmi_scan_adaptive_dwell_parameters_tlv *cmd;
  1956. wmi_buf_t buf;
  1957. uint8_t *buf_ptr;
  1958. int32_t err;
  1959. int len;
  1960. len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
  1961. len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
  1962. len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
  1963. buf = wmi_buf_alloc(wmi_handle, len);
  1964. if (!buf) {
  1965. return QDF_STATUS_E_NOMEM;
  1966. }
  1967. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1968. dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
  1969. WMITLV_SET_HDR(&dwell_param->tlv_header,
  1970. WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
  1971. WMITLV_GET_STRUCT_TLVLEN
  1972. (wmi_scan_adaptive_dwell_config_fixed_param));
  1973. dwell_param->enable = dwelltime_params->is_enabled;
  1974. buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
  1975. WMITLV_SET_HDR(buf_ptr,
  1976. WMITLV_TAG_ARRAY_STRUC,
  1977. sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
  1978. buf_ptr += WMI_TLV_HDR_SIZE;
  1979. cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
  1980. WMITLV_SET_HDR(&cmd->tlv_header,
  1981. WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
  1982. WMITLV_GET_STRUCT_TLVLEN(
  1983. wmi_scan_adaptive_dwell_parameters_tlv));
  1984. cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
  1985. cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
  1986. cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
  1987. cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
  1988. wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0);
  1989. err = wmi_unified_cmd_send(wmi_handle, buf,
  1990. len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
  1991. if (err) {
  1992. WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
  1993. wmi_buf_free(buf);
  1994. return QDF_STATUS_E_FAILURE;
  1995. }
  1996. return QDF_STATUS_SUCCESS;
  1997. }
  1998. /**
  1999. * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
  2000. * configuration params
  2001. * @wmi_handle: wmi handler
  2002. * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
  2003. *
  2004. * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
  2005. */
  2006. static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
  2007. struct wmi_dbs_scan_sel_params *dbs_scan_params)
  2008. {
  2009. wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
  2010. wmi_scan_dbs_duty_cycle_tlv_param *cmd;
  2011. wmi_buf_t buf;
  2012. uint8_t *buf_ptr;
  2013. QDF_STATUS err;
  2014. uint32_t i;
  2015. int len;
  2016. len = sizeof(*dbs_scan_param);
  2017. len += WMI_TLV_HDR_SIZE;
  2018. len += dbs_scan_params->num_clients * sizeof(*cmd);
  2019. buf = wmi_buf_alloc(wmi_handle, len);
  2020. if (!buf) {
  2021. return QDF_STATUS_E_NOMEM;
  2022. }
  2023. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  2024. dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
  2025. WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
  2026. WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
  2027. WMITLV_GET_STRUCT_TLVLEN
  2028. (wmi_scan_dbs_duty_cycle_fixed_param));
  2029. dbs_scan_param->num_clients = dbs_scan_params->num_clients;
  2030. dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
  2031. buf_ptr += sizeof(*dbs_scan_param);
  2032. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  2033. (sizeof(*cmd) * dbs_scan_params->num_clients));
  2034. buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
  2035. for (i = 0; i < dbs_scan_params->num_clients; i++) {
  2036. cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
  2037. WMITLV_SET_HDR(&cmd->tlv_header,
  2038. WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
  2039. WMITLV_GET_STRUCT_TLVLEN(
  2040. wmi_scan_dbs_duty_cycle_tlv_param));
  2041. cmd->module_id = dbs_scan_params->module_id[i];
  2042. cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
  2043. cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
  2044. buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
  2045. }
  2046. wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0);
  2047. err = wmi_unified_cmd_send(wmi_handle, buf,
  2048. len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
  2049. if (QDF_IS_STATUS_ERROR(err)) {
  2050. WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
  2051. wmi_buf_free(buf);
  2052. return QDF_STATUS_E_FAILURE;
  2053. }
  2054. return QDF_STATUS_SUCCESS;
  2055. }
  2056. /**
  2057. * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
  2058. * @wmi_handle: wmi handler
  2059. * @req_buf: set arp stats request buffer
  2060. *
  2061. * Return: 0 for success and non zero for failure
  2062. */
  2063. static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
  2064. struct set_arp_stats *req_buf)
  2065. {
  2066. wmi_buf_t buf = NULL;
  2067. QDF_STATUS status;
  2068. int len;
  2069. uint8_t *buf_ptr;
  2070. wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
  2071. len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
  2072. if (req_buf->pkt_type_bitmap) {
  2073. len += WMI_TLV_HDR_SIZE;
  2074. len += sizeof(wmi_vdev_set_connectivity_check_stats);
  2075. }
  2076. buf = wmi_buf_alloc(wmi_handle, len);
  2077. if (!buf) {
  2078. return QDF_STATUS_E_NOMEM;
  2079. }
  2080. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  2081. wmi_set_arp =
  2082. (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
  2083. WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
  2084. WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
  2085. WMITLV_GET_STRUCT_TLVLEN
  2086. (wmi_vdev_set_arp_stats_cmd_fixed_param));
  2087. /* fill in per roam config values */
  2088. wmi_set_arp->vdev_id = req_buf->vdev_id;
  2089. wmi_set_arp->set_clr = req_buf->flag;
  2090. wmi_set_arp->pkt_type = req_buf->pkt_type;
  2091. wmi_set_arp->ipv4 = req_buf->ip_addr;
  2092. WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
  2093. wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
  2094. wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
  2095. /*
  2096. * pkt_type_bitmap should be non-zero to ensure
  2097. * presence of additional stats.
  2098. */
  2099. if (req_buf->pkt_type_bitmap) {
  2100. wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
  2101. buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
  2102. WMITLV_SET_HDR(buf_ptr,
  2103. WMITLV_TAG_ARRAY_STRUC,
  2104. sizeof(wmi_vdev_set_connectivity_check_stats));
  2105. buf_ptr += WMI_TLV_HDR_SIZE;
  2106. wmi_set_connect_stats =
  2107. (wmi_vdev_set_connectivity_check_stats *)buf_ptr;
  2108. WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
  2109. WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
  2110. WMITLV_GET_STRUCT_TLVLEN(
  2111. wmi_vdev_set_connectivity_check_stats));
  2112. wmi_set_connect_stats->pkt_type_bitmap =
  2113. req_buf->pkt_type_bitmap;
  2114. wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
  2115. wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
  2116. wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
  2117. WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
  2118. wmi_set_connect_stats->pkt_type_bitmap,
  2119. wmi_set_connect_stats->tcp_src_port,
  2120. wmi_set_connect_stats->tcp_dst_port,
  2121. wmi_set_connect_stats->icmp_ipv4);
  2122. }
  2123. /* Send per roam config parameters */
  2124. wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0);
  2125. status = wmi_unified_cmd_send(wmi_handle, buf,
  2126. len, WMI_VDEV_SET_ARP_STAT_CMDID);
  2127. if (QDF_IS_STATUS_ERROR(status)) {
  2128. WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
  2129. status);
  2130. goto error;
  2131. }
  2132. WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"),
  2133. req_buf->flag, req_buf->vdev_id);
  2134. return QDF_STATUS_SUCCESS;
  2135. error:
  2136. wmi_buf_free(buf);
  2137. return status;
  2138. }
  2139. /**
  2140. * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
  2141. * @wmi_handle: wmi handler
  2142. * @req_buf: get arp stats request buffer
  2143. *
  2144. * Return: 0 for success and non zero for failure
  2145. */
  2146. static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
  2147. struct get_arp_stats *req_buf)
  2148. {
  2149. wmi_buf_t buf = NULL;
  2150. QDF_STATUS status;
  2151. int len;
  2152. uint8_t *buf_ptr;
  2153. wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
  2154. len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
  2155. buf = wmi_buf_alloc(wmi_handle, len);
  2156. if (!buf) {
  2157. return QDF_STATUS_E_NOMEM;
  2158. }
  2159. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  2160. get_arp_stats =
  2161. (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
  2162. WMITLV_SET_HDR(&get_arp_stats->tlv_header,
  2163. WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
  2164. WMITLV_GET_STRUCT_TLVLEN
  2165. (wmi_vdev_get_arp_stats_cmd_fixed_param));
  2166. /* fill in arp stats req cmd values */
  2167. get_arp_stats->vdev_id = req_buf->vdev_id;
  2168. WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
  2169. /* Send per roam config parameters */
  2170. wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0);
  2171. status = wmi_unified_cmd_send(wmi_handle, buf,
  2172. len, WMI_VDEV_GET_ARP_STAT_CMDID);
  2173. if (QDF_IS_STATUS_ERROR(status)) {
  2174. WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
  2175. status);
  2176. goto error;
  2177. }
  2178. return QDF_STATUS_SUCCESS;
  2179. error:
  2180. wmi_buf_free(buf);
  2181. return status;
  2182. }
  2183. void wmi_sta_attach_tlv(wmi_unified_t wmi_handle)
  2184. {
  2185. struct wmi_ops *ops = wmi_handle->ops;
  2186. ops->send_set_sta_sa_query_param_cmd =
  2187. send_set_sta_sa_query_param_cmd_tlv;
  2188. ops->send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv;
  2189. ops->send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv;
  2190. ops->send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv;
  2191. ops->send_get_link_speed_cmd = send_get_link_speed_cmd_tlv;
  2192. ops->send_fw_profiling_cmd = send_fw_profiling_cmd_tlv;
  2193. ops->send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv;
  2194. ops->send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv;
  2195. ops->send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv;
  2196. ops->send_set_base_macaddr_indicate_cmd =
  2197. send_set_base_macaddr_indicate_cmd_tlv;
  2198. ops->send_sar_limit_cmd = send_sar_limit_cmd_tlv;
  2199. ops->get_sar_limit_cmd = get_sar_limit_cmd_tlv;
  2200. ops->extract_sar_limit_event = extract_sar_limit_event_tlv;
  2201. ops->extract_sar2_result_event = extract_sar2_result_event_tlv;
  2202. ops->send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv;
  2203. ops->send_del_ts_cmd = send_del_ts_cmd_tlv;
  2204. ops->send_aggr_qos_cmd = send_aggr_qos_cmd_tlv;
  2205. ops->send_add_ts_cmd = send_add_ts_cmd_tlv;
  2206. ops->send_process_add_periodic_tx_ptrn_cmd =
  2207. send_process_add_periodic_tx_ptrn_cmd_tlv;
  2208. ops->send_process_del_periodic_tx_ptrn_cmd =
  2209. send_process_del_periodic_tx_ptrn_cmd_tlv;
  2210. ops->send_set_auto_shutdown_timer_cmd =
  2211. send_set_auto_shutdown_timer_cmd_tlv;
  2212. ops->send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv;
  2213. ops->send_process_ch_avoid_update_cmd =
  2214. send_process_ch_avoid_update_cmd_tlv;
  2215. ops->send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv;
  2216. ops->send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv;
  2217. ops->send_adapt_dwelltime_params_cmd =
  2218. send_adapt_dwelltime_params_cmd_tlv;
  2219. ops->send_dbs_scan_sel_params_cmd =
  2220. send_dbs_scan_sel_params_cmd_tlv;
  2221. ops->send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv;
  2222. ops->send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv;
  2223. wmi_tdls_attach_tlv(wmi_handle);
  2224. wmi_disa_attach_tlv(wmi_handle);
  2225. wmi_policy_mgr_attach_tlv(wmi_handle);
  2226. wmi_nan_feature_attach_tlv(wmi_handle);
  2227. }