wmi_unified_sta_tlv.c 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507
  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 CONVERGED_TDLS_ENABLE
  461. /**
  462. * tdls_get_wmi_offchannel_mode - Get WMI tdls off channel mode
  463. * @tdls_sw_mode: tdls_sw_mode
  464. *
  465. * This function returns wmi tdls offchannel mode
  466. *
  467. * Return: enum value of wmi tdls offchannel mode
  468. */
  469. static uint8_t tdls_get_wmi_offchannel_mode(uint8_t tdls_sw_mode)
  470. {
  471. uint8_t off_chan_mode;
  472. switch (tdls_sw_mode) {
  473. case ENABLE_CHANSWITCH:
  474. off_chan_mode = WMI_TDLS_ENABLE_OFFCHANNEL;
  475. break;
  476. case DISABLE_CHANSWITCH:
  477. off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
  478. break;
  479. default:
  480. WMI_LOGD(FL("unknown tdls_sw_mode %d"), tdls_sw_mode);
  481. off_chan_mode = WMI_TDLS_DISABLE_OFFCHANNEL;
  482. }
  483. return off_chan_mode;
  484. }
  485. /**
  486. * tdls_get_wmi_offchannel_bw - Get WMI tdls off channel Bandwidth
  487. * @tdls_sw_mode: tdls_sw_mode
  488. *
  489. * This function returns wmi tdls offchannel bandwidth
  490. *
  491. * Return: TDLS offchannel bandwidth
  492. */
  493. static uint8_t tdls_get_wmi_offchannel_bw(uint16_t tdls_off_ch_bw_offset)
  494. {
  495. uint8_t off_chan_bw;
  496. switch (tdls_off_ch_bw_offset) {
  497. case BW20:
  498. off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
  499. break;
  500. case BW40_LOW_PRIMARY:
  501. case BW40_HIGH_PRIMARY:
  502. off_chan_bw = WMI_TDLS_OFFCHAN_40MHZ;
  503. break;
  504. case BW80:
  505. off_chan_bw = WMI_TDLS_OFFCHAN_80MHZ;
  506. case BWALL:
  507. off_chan_bw = WMI_TDLS_OFFCHAN_160MHZ;
  508. default:
  509. WMI_LOGD(FL("unknown tdls offchannel bw offset %d"),
  510. tdls_off_ch_bw_offset);
  511. off_chan_bw = WMI_TDLS_OFFCHAN_20MHZ;
  512. }
  513. return off_chan_bw;
  514. }
  515. /**
  516. * send_set_tdls_offchan_mode_cmd_tlv() - set tdls off channel mode
  517. * @wmi_handle: wmi handle
  518. * @chan_switch_params: Pointer to tdls channel switch parameter structure
  519. *
  520. * This function sets tdls off channel mode
  521. *
  522. * Return: 0 on success; Negative errno otherwise
  523. */
  524. static QDF_STATUS send_set_tdls_offchan_mode_cmd_tlv(wmi_unified_t wmi_handle,
  525. struct tdls_channel_switch_params *chan_switch_params)
  526. {
  527. wmi_tdls_set_offchan_mode_cmd_fixed_param *cmd;
  528. wmi_buf_t wmi_buf;
  529. u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param);
  530. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  531. if (!wmi_buf) {
  532. return QDF_STATUS_E_FAILURE;
  533. }
  534. cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param *)
  535. wmi_buf_data(wmi_buf);
  536. WMITLV_SET_HDR(&cmd->tlv_header,
  537. WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param,
  538. WMITLV_GET_STRUCT_TLVLEN(
  539. wmi_tdls_set_offchan_mode_cmd_fixed_param));
  540. WMI_CHAR_ARRAY_TO_MAC_ADDR(chan_switch_params->peer_mac_addr,
  541. &cmd->peer_macaddr);
  542. cmd->vdev_id = chan_switch_params->vdev_id;
  543. cmd->offchan_mode =
  544. tdls_get_wmi_offchannel_mode(chan_switch_params->tdls_sw_mode);
  545. cmd->is_peer_responder = chan_switch_params->is_responder;
  546. cmd->offchan_num = chan_switch_params->tdls_off_ch;
  547. cmd->offchan_bw_bitmap =
  548. tdls_get_wmi_offchannel_bw(
  549. chan_switch_params->tdls_off_ch_bw_offset);
  550. cmd->offchan_oper_class = chan_switch_params->oper_class;
  551. WMI_LOGD(FL("Peer MAC Addr mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"),
  552. cmd->peer_macaddr.mac_addr31to0,
  553. cmd->peer_macaddr.mac_addr47to32);
  554. WMI_LOGD(FL(
  555. "vdev_id: %d, off channel mode: %d, off channel Num: %d, "
  556. "off channel offset: 0x%x, is_peer_responder: %d, operating class: %d"
  557. ),
  558. cmd->vdev_id,
  559. cmd->offchan_mode,
  560. cmd->offchan_num,
  561. cmd->offchan_bw_bitmap,
  562. cmd->is_peer_responder,
  563. cmd->offchan_oper_class);
  564. wmi_mtrace(WMI_TDLS_SET_OFFCHAN_MODE_CMDID, cmd->vdev_id, 0);
  565. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  566. WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) {
  567. WMI_LOGP(FL("failed to send tdls off chan command"));
  568. wmi_buf_free(wmi_buf);
  569. return QDF_STATUS_E_FAILURE;
  570. }
  571. return QDF_STATUS_SUCCESS;
  572. }
  573. /**
  574. * send_update_fw_tdls_state_cmd_tlv() - send enable/disable tdls for a vdev
  575. * @wmi_handle: wmi handle
  576. * @pwmaTdlsparams: TDLS params
  577. *
  578. * Return: 0 for success or error code
  579. */
  580. static QDF_STATUS send_update_fw_tdls_state_cmd_tlv(wmi_unified_t wmi_handle,
  581. void *tdls_param, uint8_t tdls_state)
  582. {
  583. wmi_tdls_set_state_cmd_fixed_param *cmd;
  584. wmi_buf_t wmi_buf;
  585. struct wmi_tdls_params *wmi_tdls = (struct wmi_tdls_params *) tdls_param;
  586. uint16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param);
  587. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  588. if (!wmi_buf) {
  589. return QDF_STATUS_E_FAILURE;
  590. }
  591. cmd = (wmi_tdls_set_state_cmd_fixed_param *) wmi_buf_data(wmi_buf);
  592. WMITLV_SET_HDR(&cmd->tlv_header,
  593. WMITLV_TAG_STRUC_wmi_tdls_set_state_cmd_fixed_param,
  594. WMITLV_GET_STRUCT_TLVLEN
  595. (wmi_tdls_set_state_cmd_fixed_param));
  596. cmd->vdev_id = wmi_tdls->vdev_id;
  597. cmd->state = tdls_state;
  598. cmd->notification_interval_ms = wmi_tdls->notification_interval_ms;
  599. cmd->tx_discovery_threshold = wmi_tdls->tx_discovery_threshold;
  600. cmd->tx_teardown_threshold = wmi_tdls->tx_teardown_threshold;
  601. cmd->rssi_teardown_threshold = wmi_tdls->rssi_teardown_threshold;
  602. cmd->rssi_delta = wmi_tdls->rssi_delta;
  603. cmd->tdls_options = wmi_tdls->tdls_options;
  604. cmd->tdls_peer_traffic_ind_window = wmi_tdls->peer_traffic_ind_window;
  605. cmd->tdls_peer_traffic_response_timeout_ms =
  606. wmi_tdls->peer_traffic_response_timeout;
  607. cmd->tdls_puapsd_mask = wmi_tdls->puapsd_mask;
  608. cmd->tdls_puapsd_inactivity_time_ms = wmi_tdls->puapsd_inactivity_time;
  609. cmd->tdls_puapsd_rx_frame_threshold =
  610. wmi_tdls->puapsd_rx_frame_threshold;
  611. cmd->teardown_notification_ms =
  612. wmi_tdls->teardown_notification_ms;
  613. cmd->tdls_peer_kickout_threshold =
  614. wmi_tdls->tdls_peer_kickout_threshold;
  615. WMI_LOGD("%s: tdls_state: %d, state: %d, "
  616. "notification_interval_ms: %d, "
  617. "tx_discovery_threshold: %d, "
  618. "tx_teardown_threshold: %d, "
  619. "rssi_teardown_threshold: %d, "
  620. "rssi_delta: %d, "
  621. "tdls_options: 0x%x, "
  622. "tdls_peer_traffic_ind_window: %d, "
  623. "tdls_peer_traffic_response_timeout: %d, "
  624. "tdls_puapsd_mask: 0x%x, "
  625. "tdls_puapsd_inactivity_time: %d, "
  626. "tdls_puapsd_rx_frame_threshold: %d, "
  627. "teardown_notification_ms: %d, "
  628. "tdls_peer_kickout_threshold: %d",
  629. __func__, tdls_state, cmd->state,
  630. cmd->notification_interval_ms,
  631. cmd->tx_discovery_threshold,
  632. cmd->tx_teardown_threshold,
  633. cmd->rssi_teardown_threshold,
  634. cmd->rssi_delta,
  635. cmd->tdls_options,
  636. cmd->tdls_peer_traffic_ind_window,
  637. cmd->tdls_peer_traffic_response_timeout_ms,
  638. cmd->tdls_puapsd_mask,
  639. cmd->tdls_puapsd_inactivity_time_ms,
  640. cmd->tdls_puapsd_rx_frame_threshold,
  641. cmd->teardown_notification_ms,
  642. cmd->tdls_peer_kickout_threshold);
  643. wmi_mtrace(WMI_TDLS_SET_STATE_CMDID, cmd->vdev_id, 0);
  644. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  645. WMI_TDLS_SET_STATE_CMDID)) {
  646. WMI_LOGP("%s: failed to send tdls set state command", __func__);
  647. wmi_buf_free(wmi_buf);
  648. return QDF_STATUS_E_FAILURE;
  649. }
  650. WMI_LOGD("%s: vdev_id %d", __func__, wmi_tdls->vdev_id);
  651. return QDF_STATUS_SUCCESS;
  652. }
  653. /**
  654. * send_update_tdls_peer_state_cmd_tlv() - update TDLS peer state
  655. * @wmi_handle: wmi handle
  656. * @peerStateParams: TDLS peer state params
  657. *
  658. * Return: QDF_STATUS_SUCCESS for success or error code
  659. */
  660. static QDF_STATUS send_update_tdls_peer_state_cmd_tlv(wmi_unified_t wmi_handle,
  661. struct tdls_peer_state_params *peerStateParams,
  662. uint32_t *ch_mhz)
  663. {
  664. wmi_tdls_peer_update_cmd_fixed_param *cmd;
  665. wmi_tdls_peer_capabilities *peer_cap;
  666. wmi_channel *chan_info;
  667. wmi_buf_t wmi_buf;
  668. uint8_t *buf_ptr;
  669. uint32_t i;
  670. int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) +
  671. sizeof(wmi_tdls_peer_capabilities);
  672. len += WMI_TLV_HDR_SIZE +
  673. sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen;
  674. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  675. if (!wmi_buf) {
  676. return QDF_STATUS_E_FAILURE;
  677. }
  678. buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
  679. cmd = (wmi_tdls_peer_update_cmd_fixed_param *) buf_ptr;
  680. WMITLV_SET_HDR(&cmd->tlv_header,
  681. WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param,
  682. WMITLV_GET_STRUCT_TLVLEN
  683. (wmi_tdls_peer_update_cmd_fixed_param));
  684. cmd->vdev_id = peerStateParams->vdevId;
  685. WMI_CHAR_ARRAY_TO_MAC_ADDR(peerStateParams->peerMacAddr,
  686. &cmd->peer_macaddr);
  687. cmd->peer_state = peerStateParams->peerState;
  688. WMI_LOGD("%s: vdev_id: %d, peerStateParams->peerMacAddr: %pM, "
  689. "peer_macaddr.mac_addr31to0: 0x%x, "
  690. "peer_macaddr.mac_addr47to32: 0x%x, peer_state: %d",
  691. __func__, cmd->vdev_id, peerStateParams->peerMacAddr,
  692. cmd->peer_macaddr.mac_addr31to0,
  693. cmd->peer_macaddr.mac_addr47to32, cmd->peer_state);
  694. buf_ptr += sizeof(wmi_tdls_peer_update_cmd_fixed_param);
  695. peer_cap = (wmi_tdls_peer_capabilities *) buf_ptr;
  696. WMITLV_SET_HDR(&peer_cap->tlv_header,
  697. WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities,
  698. WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities));
  699. if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3)
  700. WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap);
  701. if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2)
  702. WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap);
  703. if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1)
  704. WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap);
  705. if (peerStateParams->peerCap.peerUapsdQueue & 0x01)
  706. WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap);
  707. /* Ack and More Data Ack are sent as 0, so no need to set
  708. * but fill SP
  709. */
  710. WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap,
  711. peerStateParams->peerCap.peerMaxSp);
  712. peer_cap->buff_sta_support =
  713. peerStateParams->peerCap.peerBuffStaSupport;
  714. peer_cap->off_chan_support =
  715. peerStateParams->peerCap.peerOffChanSupport;
  716. peer_cap->peer_curr_operclass =
  717. peerStateParams->peerCap.peerCurrOperClass;
  718. /* self curr operclass is not being used and so pass op class for
  719. * preferred off chan in it.
  720. */
  721. peer_cap->self_curr_operclass =
  722. peerStateParams->peerCap.opClassForPrefOffChan;
  723. peer_cap->peer_chan_len = peerStateParams->peerCap.peerChanLen;
  724. peer_cap->peer_operclass_len =
  725. peerStateParams->peerCap.peerOperClassLen;
  726. WMI_LOGD("%s: peer_operclass_len: %d",
  727. __func__, peer_cap->peer_operclass_len);
  728. for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) {
  729. peer_cap->peer_operclass[i] =
  730. peerStateParams->peerCap.peerOperClass[i];
  731. WMI_LOGD("%s: peer_operclass[%d]: %d",
  732. __func__, i, peer_cap->peer_operclass[i]);
  733. }
  734. peer_cap->is_peer_responder = peerStateParams->peerCap.isPeerResponder;
  735. peer_cap->pref_offchan_num = peerStateParams->peerCap.prefOffChanNum;
  736. peer_cap->pref_offchan_bw =
  737. peerStateParams->peerCap.prefOffChanBandwidth;
  738. WMI_LOGD
  739. ("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, "
  740. "peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: "
  741. "%d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num:"
  742. " %d, pref_offchan_bw: %d",
  743. __func__, peer_cap->peer_qos, peer_cap->buff_sta_support,
  744. peer_cap->off_chan_support, peer_cap->peer_curr_operclass,
  745. peer_cap->self_curr_operclass, peer_cap->peer_chan_len,
  746. peer_cap->peer_operclass_len, peer_cap->is_peer_responder,
  747. peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw);
  748. /* next fill variable size array of peer chan info */
  749. buf_ptr += sizeof(wmi_tdls_peer_capabilities);
  750. WMITLV_SET_HDR(buf_ptr,
  751. WMITLV_TAG_ARRAY_STRUC,
  752. sizeof(wmi_channel) *
  753. peerStateParams->peerCap.peerChanLen);
  754. chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE);
  755. for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) {
  756. WMITLV_SET_HDR(&chan_info->tlv_header,
  757. WMITLV_TAG_STRUC_wmi_channel,
  758. WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
  759. chan_info->mhz = ch_mhz[i];
  760. chan_info->band_center_freq1 = chan_info->mhz;
  761. chan_info->band_center_freq2 = 0;
  762. WMI_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz);
  763. if (peerStateParams->peerCap.peerChan[i].dfsSet) {
  764. WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE);
  765. WMI_LOGI("chan[%d] DFS[%d]\n",
  766. peerStateParams->peerCap.peerChan[i].chanId,
  767. peerStateParams->peerCap.peerChan[i].dfsSet);
  768. }
  769. if (chan_info->mhz < WMI_2_4_GHZ_MAX_FREQ)
  770. WMI_SET_CHANNEL_MODE(chan_info, MODE_11G);
  771. else
  772. WMI_SET_CHANNEL_MODE(chan_info, MODE_11A);
  773. WMI_SET_CHANNEL_MAX_TX_POWER(chan_info,
  774. peerStateParams->peerCap.
  775. peerChan[i].pwr);
  776. WMI_SET_CHANNEL_REG_POWER(chan_info,
  777. peerStateParams->peerCap.peerChan[i].
  778. pwr);
  779. WMI_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz,
  780. peerStateParams->peerCap.peerChan[i].pwr);
  781. chan_info++;
  782. }
  783. wmi_mtrace(WMI_TDLS_PEER_UPDATE_CMDID, cmd->vdev_id, 0);
  784. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  785. WMI_TDLS_PEER_UPDATE_CMDID)) {
  786. WMI_LOGE("%s: failed to send tdls peer update state command",
  787. __func__);
  788. wmi_buf_free(wmi_buf);
  789. return QDF_STATUS_E_FAILURE;
  790. }
  791. return QDF_STATUS_SUCCESS;
  792. }
  793. /**
  794. * extract_vdev_tdls_ev_param_tlv() - extract vdev tdls param from event
  795. * @wmi_handle: wmi handle
  796. * @param evt_buf: pointer to event buffer
  797. * @param param: Pointer to hold vdev tdls param
  798. *
  799. * Return: QDF_STATUS_SUCCESS for success or error code
  800. */
  801. static QDF_STATUS extract_vdev_tdls_ev_param_tlv(wmi_unified_t wmi_handle,
  802. void *evt_buf, struct tdls_event_info *param)
  803. {
  804. WMI_TDLS_PEER_EVENTID_param_tlvs *param_buf;
  805. wmi_tdls_peer_event_fixed_param *evt;
  806. param_buf = (WMI_TDLS_PEER_EVENTID_param_tlvs *)evt_buf;
  807. if (!param_buf) {
  808. WMI_LOGE("%s: NULL param_buf", __func__);
  809. return QDF_STATUS_E_NULL_VALUE;
  810. }
  811. evt = param_buf->fixed_param;
  812. qdf_mem_zero(param, sizeof(*param));
  813. param->vdev_id = evt->vdev_id;
  814. WMI_MAC_ADDR_TO_CHAR_ARRAY(&evt->peer_macaddr,
  815. param->peermac.bytes);
  816. switch (evt->peer_status) {
  817. case WMI_TDLS_SHOULD_DISCOVER:
  818. param->message_type = TDLS_SHOULD_DISCOVER;
  819. break;
  820. case WMI_TDLS_SHOULD_TEARDOWN:
  821. param->message_type = TDLS_SHOULD_TEARDOWN;
  822. break;
  823. case WMI_TDLS_PEER_DISCONNECTED:
  824. param->message_type = TDLS_PEER_DISCONNECTED;
  825. break;
  826. case WMI_TDLS_CONNECTION_TRACKER_NOTIFICATION:
  827. param->message_type = TDLS_CONNECTION_TRACKER_NOTIFY;
  828. break;
  829. default:
  830. WMI_LOGE("%s: Discarding unknown tdls event %d from target",
  831. __func__, evt->peer_status);
  832. return QDF_STATUS_E_INVAL;
  833. };
  834. switch (evt->peer_reason) {
  835. case WMI_TDLS_TEARDOWN_REASON_TX:
  836. param->peer_reason = TDLS_TEARDOWN_TX;
  837. break;
  838. case WMI_TDLS_TEARDOWN_REASON_RSSI:
  839. param->peer_reason = TDLS_TEARDOWN_RSSI;
  840. break;
  841. case WMI_TDLS_TEARDOWN_REASON_SCAN:
  842. param->peer_reason = TDLS_TEARDOWN_SCAN;
  843. break;
  844. case WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE:
  845. param->peer_reason = TDLS_DISCONNECTED_PEER_DELETE;
  846. break;
  847. case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
  848. param->peer_reason = TDLS_TEARDOWN_PTR_TIMEOUT;
  849. break;
  850. case WMI_TDLS_TEARDOWN_REASON_BAD_PTR:
  851. param->peer_reason = TDLS_TEARDOWN_BAD_PTR;
  852. break;
  853. case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
  854. param->peer_reason = TDLS_TEARDOWN_NO_RSP;
  855. break;
  856. case WMI_TDLS_ENTER_BUF_STA:
  857. param->peer_reason = TDLS_PEER_ENTER_BUF_STA;
  858. break;
  859. case WMI_TDLS_EXIT_BUF_STA:
  860. param->peer_reason = TDLS_PEER_EXIT_BUF_STA;
  861. break;
  862. case WMI_TDLS_ENTER_BT_BUSY_MODE:
  863. param->peer_reason = TDLS_ENTER_BT_BUSY;
  864. break;
  865. case WMI_TDLS_EXIT_BT_BUSY_MODE:
  866. param->peer_reason = TDLS_EXIT_BT_BUSY;
  867. break;
  868. case WMI_TDLS_SCAN_STARTED_EVENT:
  869. param->peer_reason = TDLS_SCAN_STARTED;
  870. break;
  871. case WMI_TDLS_SCAN_COMPLETED_EVENT:
  872. param->peer_reason = TDLS_SCAN_COMPLETED;
  873. break;
  874. default:
  875. WMI_LOGE("%s: unknown reason %d in tdls event %d from target",
  876. __func__, evt->peer_reason, evt->peer_status);
  877. return QDF_STATUS_E_INVAL;
  878. };
  879. WMI_LOGD("%s: tdls event, peer: %pM, type: 0x%x, reason: %d, vdev: %d",
  880. __func__, param->peermac.bytes, param->message_type,
  881. param->peer_reason, param->vdev_id);
  882. return QDF_STATUS_SUCCESS;
  883. }
  884. void wmi_tdls_attach_tlv(struct wmi_unified *wmi_handle)
  885. {
  886. struct wmi_ops *ops = wmi_handle->ops;
  887. ops->send_set_tdls_offchan_mode_cmd =
  888. send_set_tdls_offchan_mode_cmd_tlv;
  889. ops->send_update_fw_tdls_state_cmd =
  890. send_update_fw_tdls_state_cmd_tlv;
  891. ops->send_update_tdls_peer_state_cmd =
  892. send_update_tdls_peer_state_cmd_tlv;
  893. ops->extract_vdev_tdls_ev_param = extract_vdev_tdls_ev_param_tlv;
  894. }
  895. #endif /* CONVERGED_TDLS_ENABLE */
  896. /*
  897. * send_process_set_ie_info_cmd_tlv() - Function to send IE info to firmware
  898. * @wmi_handle: Pointer to WMi handle
  899. * @ie_data: Pointer for ie data
  900. *
  901. * This function sends IE information to firmware
  902. *
  903. * Return: QDF_STATUS_SUCCESS for success otherwise failure
  904. *
  905. */
  906. static QDF_STATUS send_process_set_ie_info_cmd_tlv(wmi_unified_t wmi_handle,
  907. struct vdev_ie_info_param *ie_info)
  908. {
  909. wmi_vdev_set_ie_cmd_fixed_param *cmd;
  910. wmi_buf_t buf;
  911. uint8_t *buf_ptr;
  912. uint32_t len, ie_len_aligned;
  913. QDF_STATUS ret;
  914. ie_len_aligned = roundup(ie_info->length, sizeof(uint32_t));
  915. /* Allocate memory for the WMI command */
  916. len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + ie_len_aligned;
  917. buf = wmi_buf_alloc(wmi_handle, len);
  918. if (!buf) {
  919. return QDF_STATUS_E_NOMEM;
  920. }
  921. buf_ptr = wmi_buf_data(buf);
  922. qdf_mem_zero(buf_ptr, len);
  923. /* Populate the WMI command */
  924. cmd = (wmi_vdev_set_ie_cmd_fixed_param *)buf_ptr;
  925. WMITLV_SET_HDR(&cmd->tlv_header,
  926. WMITLV_TAG_STRUC_wmi_vdev_set_ie_cmd_fixed_param,
  927. WMITLV_GET_STRUCT_TLVLEN(
  928. wmi_vdev_set_ie_cmd_fixed_param));
  929. cmd->vdev_id = ie_info->vdev_id;
  930. cmd->ie_id = ie_info->ie_id;
  931. cmd->ie_len = ie_info->length;
  932. cmd->band = ie_info->band;
  933. WMI_LOGD(FL("IE:%d of size:%d sent for vdev:%d"), ie_info->ie_id,
  934. ie_info->length, ie_info->vdev_id);
  935. buf_ptr += sizeof(*cmd);
  936. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_aligned);
  937. buf_ptr += WMI_TLV_HDR_SIZE;
  938. qdf_mem_copy(buf_ptr, ie_info->data, cmd->ie_len);
  939. wmi_mtrace(WMI_VDEV_SET_IE_CMDID, cmd->vdev_id, 0);
  940. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  941. WMI_VDEV_SET_IE_CMDID);
  942. if (QDF_IS_STATUS_ERROR(ret)) {
  943. WMI_LOGE(FL("Failed to send set IE command ret = %d"), ret);
  944. wmi_buf_free(buf);
  945. }
  946. return ret;
  947. }
  948. /**
  949. * send_set_base_macaddr_indicate_cmd_tlv() - set base mac address in fw
  950. * @wmi_handle: wmi handle
  951. * @custom_addr: base mac address
  952. *
  953. * Return: QDF_STATUS_SUCCESS for success or error code
  954. */
  955. static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handle,
  956. uint8_t *custom_addr)
  957. {
  958. wmi_pdev_set_base_macaddr_cmd_fixed_param *cmd;
  959. wmi_buf_t buf;
  960. int err;
  961. buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
  962. if (!buf) {
  963. return QDF_STATUS_E_NOMEM;
  964. }
  965. cmd = (wmi_pdev_set_base_macaddr_cmd_fixed_param *) wmi_buf_data(buf);
  966. qdf_mem_zero(cmd, sizeof(*cmd));
  967. WMITLV_SET_HDR(&cmd->tlv_header,
  968. WMITLV_TAG_STRUC_wmi_pdev_set_base_macaddr_cmd_fixed_param,
  969. WMITLV_GET_STRUCT_TLVLEN
  970. (wmi_pdev_set_base_macaddr_cmd_fixed_param));
  971. WMI_CHAR_ARRAY_TO_MAC_ADDR(custom_addr, &cmd->base_macaddr);
  972. cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
  973. WMI_HOST_PDEV_ID_SOC);
  974. wmi_mtrace(WMI_PDEV_SET_BASE_MACADDR_CMDID, NO_SESSION, 0);
  975. err = wmi_unified_cmd_send(wmi_handle, buf,
  976. sizeof(*cmd),
  977. WMI_PDEV_SET_BASE_MACADDR_CMDID);
  978. if (err) {
  979. WMI_LOGE("Failed to send set_base_macaddr cmd");
  980. wmi_buf_free(buf);
  981. return QDF_STATUS_E_FAILURE;
  982. }
  983. return 0;
  984. }
  985. #ifdef WLAN_FEATURE_DISA
  986. /**
  987. * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw
  988. * @wmi_handle: wmi handle
  989. * @params: encrypt/decrypt params
  990. *
  991. * Return: QDF_STATUS_SUCCESS for success or error code
  992. */
  993. static
  994. QDF_STATUS send_encrypt_decrypt_send_cmd_tlv(wmi_unified_t wmi_handle,
  995. struct disa_encrypt_decrypt_req_params *encrypt_decrypt_params)
  996. {
  997. wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *cmd;
  998. wmi_buf_t wmi_buf;
  999. uint8_t *buf_ptr;
  1000. QDF_STATUS ret;
  1001. uint32_t len;
  1002. WMI_LOGD(FL("Send encrypt decrypt cmd"));
  1003. len = sizeof(*cmd) +
  1004. roundup(encrypt_decrypt_params->data_len, sizeof(uint32_t)) +
  1005. WMI_TLV_HDR_SIZE;
  1006. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  1007. if (!wmi_buf) {
  1008. return QDF_STATUS_E_NOMEM;
  1009. }
  1010. buf_ptr = wmi_buf_data(wmi_buf);
  1011. cmd = (wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param *)buf_ptr;
  1012. WMITLV_SET_HDR(&cmd->tlv_header,
  1013. WMITLV_TAG_STRUC_wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param,
  1014. WMITLV_GET_STRUCT_TLVLEN(
  1015. wmi_vdev_encrypt_decrypt_data_req_cmd_fixed_param));
  1016. cmd->vdev_id = encrypt_decrypt_params->vdev_id;
  1017. cmd->key_flag = encrypt_decrypt_params->key_flag;
  1018. cmd->key_idx = encrypt_decrypt_params->key_idx;
  1019. cmd->key_cipher = encrypt_decrypt_params->key_cipher;
  1020. cmd->key_len = encrypt_decrypt_params->key_len;
  1021. cmd->key_txmic_len = encrypt_decrypt_params->key_txmic_len;
  1022. cmd->key_rxmic_len = encrypt_decrypt_params->key_rxmic_len;
  1023. qdf_mem_copy(cmd->key_data, encrypt_decrypt_params->key_data,
  1024. encrypt_decrypt_params->key_len);
  1025. qdf_mem_copy(cmd->mac_hdr, encrypt_decrypt_params->mac_header,
  1026. MAX_MAC_HEADER_LEN);
  1027. cmd->data_len = encrypt_decrypt_params->data_len;
  1028. if (cmd->data_len) {
  1029. buf_ptr += sizeof(*cmd);
  1030. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
  1031. roundup(encrypt_decrypt_params->data_len,
  1032. sizeof(uint32_t)));
  1033. buf_ptr += WMI_TLV_HDR_SIZE;
  1034. qdf_mem_copy(buf_ptr, encrypt_decrypt_params->data,
  1035. encrypt_decrypt_params->data_len);
  1036. }
  1037. /* This conversion is to facilitate data to FW in little endian */
  1038. cmd->pn[5] = encrypt_decrypt_params->pn[0];
  1039. cmd->pn[4] = encrypt_decrypt_params->pn[1];
  1040. cmd->pn[3] = encrypt_decrypt_params->pn[2];
  1041. cmd->pn[2] = encrypt_decrypt_params->pn[3];
  1042. cmd->pn[1] = encrypt_decrypt_params->pn[4];
  1043. cmd->pn[0] = encrypt_decrypt_params->pn[5];
  1044. wmi_mtrace(WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, cmd->vdev_id, 0);
  1045. ret = wmi_unified_cmd_send(wmi_handle,
  1046. wmi_buf, len,
  1047. WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID);
  1048. if (QDF_IS_STATUS_ERROR(ret)) {
  1049. WMI_LOGE("Failed to send ENCRYPT DECRYPT cmd: %d", ret);
  1050. wmi_buf_free(wmi_buf);
  1051. }
  1052. return ret;
  1053. }
  1054. /**
  1055. * extract_encrypt_decrypt_resp_event_tlv() - extract encrypt decrypt resp
  1056. * params from event
  1057. * @wmi_handle: wmi handle
  1058. * @evt_buf: pointer to event buffer
  1059. * @resp: Pointer to hold resp parameters
  1060. *
  1061. * Return: QDF_STATUS_SUCCESS for success or error code
  1062. */
  1063. static
  1064. QDF_STATUS extract_encrypt_decrypt_resp_event_tlv(wmi_unified_t wmi_handle,
  1065. void *evt_buf, struct disa_encrypt_decrypt_resp_params *resp)
  1066. {
  1067. WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID_param_tlvs *param_buf;
  1068. wmi_vdev_encrypt_decrypt_data_resp_event_fixed_param *data_event;
  1069. param_buf = evt_buf;
  1070. if (!param_buf) {
  1071. WMI_LOGE("encrypt decrypt resp evt_buf is NULL");
  1072. return QDF_STATUS_E_INVAL;
  1073. }
  1074. data_event = param_buf->fixed_param;
  1075. resp->vdev_id = data_event->vdev_id;
  1076. resp->status = data_event->status;
  1077. if ((data_event->data_length > param_buf->num_enc80211_frame) ||
  1078. (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE -
  1079. sizeof(*data_event))) {
  1080. WMI_LOGE("FW msg data_len %d more than TLV hdr %d",
  1081. data_event->data_length,
  1082. param_buf->num_enc80211_frame);
  1083. return QDF_STATUS_E_INVAL;
  1084. }
  1085. resp->data_len = data_event->data_length;
  1086. if (resp->data_len)
  1087. resp->data = (uint8_t *)param_buf->enc80211_frame;
  1088. return QDF_STATUS_SUCCESS;
  1089. }
  1090. void wmi_disa_attach_tlv(struct wmi_unified *wmi_handle)
  1091. {
  1092. struct wmi_ops *ops = wmi_handle->ops;
  1093. ops->send_encrypt_decrypt_send_cmd =
  1094. send_encrypt_decrypt_send_cmd_tlv;
  1095. ops->extract_encrypt_decrypt_resp_event =
  1096. extract_encrypt_decrypt_resp_event_tlv;
  1097. }
  1098. #endif /* WLAN_FEATURE_DISA */
  1099. /**
  1100. * send_sar_limit_cmd_tlv() - send sar limit cmd to fw
  1101. * @wmi_handle: wmi handle
  1102. * @params: sar limit params
  1103. *
  1104. * Return: QDF_STATUS_SUCCESS for success or error code
  1105. */
  1106. static QDF_STATUS send_sar_limit_cmd_tlv(wmi_unified_t wmi_handle,
  1107. struct sar_limit_cmd_params *sar_limit_params)
  1108. {
  1109. wmi_buf_t buf;
  1110. QDF_STATUS qdf_status;
  1111. wmi_sar_limits_cmd_fixed_param *cmd;
  1112. int i;
  1113. uint8_t *buf_ptr;
  1114. wmi_sar_limit_cmd_row *wmi_sar_rows_list;
  1115. struct sar_limit_cmd_row *sar_rows_list;
  1116. uint32_t len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
  1117. len += sizeof(wmi_sar_limit_cmd_row) * sar_limit_params->num_limit_rows;
  1118. buf = wmi_buf_alloc(wmi_handle, len);
  1119. if (!buf) {
  1120. qdf_status = QDF_STATUS_E_NOMEM;
  1121. goto end;
  1122. }
  1123. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1124. cmd = (wmi_sar_limits_cmd_fixed_param *) buf_ptr;
  1125. WMITLV_SET_HDR(&cmd->tlv_header,
  1126. WMITLV_TAG_STRUC_wmi_sar_limits_cmd_fixed_param,
  1127. WMITLV_GET_STRUCT_TLVLEN
  1128. (wmi_sar_limits_cmd_fixed_param));
  1129. cmd->sar_enable = sar_limit_params->sar_enable;
  1130. cmd->commit_limits = sar_limit_params->commit_limits;
  1131. cmd->num_limit_rows = sar_limit_params->num_limit_rows;
  1132. WMI_LOGD("no of sar rows = %d, len = %d",
  1133. sar_limit_params->num_limit_rows, len);
  1134. buf_ptr += sizeof(*cmd);
  1135. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1136. sizeof(wmi_sar_limit_cmd_row) *
  1137. sar_limit_params->num_limit_rows);
  1138. if (cmd->num_limit_rows == 0)
  1139. goto send_sar_limits;
  1140. wmi_sar_rows_list = (wmi_sar_limit_cmd_row *)
  1141. (buf_ptr + WMI_TLV_HDR_SIZE);
  1142. sar_rows_list = sar_limit_params->sar_limit_row_list;
  1143. for (i = 0; i < sar_limit_params->num_limit_rows; i++) {
  1144. WMITLV_SET_HDR(&wmi_sar_rows_list->tlv_header,
  1145. WMITLV_TAG_STRUC_wmi_sar_limit_cmd_row,
  1146. WMITLV_GET_STRUCT_TLVLEN(wmi_sar_limit_cmd_row));
  1147. wmi_sar_rows_list->band_id = sar_rows_list->band_id;
  1148. wmi_sar_rows_list->chain_id = sar_rows_list->chain_id;
  1149. wmi_sar_rows_list->mod_id = sar_rows_list->mod_id;
  1150. wmi_sar_rows_list->limit_value = sar_rows_list->limit_value;
  1151. wmi_sar_rows_list->validity_bitmap =
  1152. sar_rows_list->validity_bitmap;
  1153. WMI_LOGD("row %d, band_id = %d, chain_id = %d, mod_id = %d, limit_value = %d, validity_bitmap = %d",
  1154. i, wmi_sar_rows_list->band_id,
  1155. wmi_sar_rows_list->chain_id,
  1156. wmi_sar_rows_list->mod_id,
  1157. wmi_sar_rows_list->limit_value,
  1158. wmi_sar_rows_list->validity_bitmap);
  1159. sar_rows_list++;
  1160. wmi_sar_rows_list++;
  1161. }
  1162. send_sar_limits:
  1163. wmi_mtrace(WMI_SAR_LIMITS_CMDID, NO_SESSION, 0);
  1164. qdf_status = wmi_unified_cmd_send(wmi_handle, buf, len,
  1165. WMI_SAR_LIMITS_CMDID);
  1166. if (QDF_IS_STATUS_ERROR(qdf_status)) {
  1167. WMI_LOGE("Failed to send WMI_SAR_LIMITS_CMDID");
  1168. wmi_buf_free(buf);
  1169. }
  1170. end:
  1171. return qdf_status;
  1172. }
  1173. static QDF_STATUS get_sar_limit_cmd_tlv(wmi_unified_t wmi_handle)
  1174. {
  1175. wmi_sar_get_limits_cmd_fixed_param *cmd;
  1176. wmi_buf_t wmi_buf;
  1177. uint32_t len;
  1178. QDF_STATUS status;
  1179. WMI_LOGD(FL("Enter"));
  1180. len = sizeof(*cmd);
  1181. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  1182. if (!wmi_buf) {
  1183. return QDF_STATUS_E_NOMEM;
  1184. }
  1185. cmd = (wmi_sar_get_limits_cmd_fixed_param *)wmi_buf_data(wmi_buf);
  1186. WMITLV_SET_HDR(&cmd->tlv_header,
  1187. WMITLV_TAG_STRUC_wmi_sar_get_limits_cmd_fixed_param,
  1188. WMITLV_GET_STRUCT_TLVLEN
  1189. (wmi_sar_get_limits_cmd_fixed_param));
  1190. cmd->reserved = 0;
  1191. wmi_mtrace(WMI_SAR_GET_LIMITS_CMDID, NO_SESSION, 0);
  1192. status = wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  1193. WMI_SAR_GET_LIMITS_CMDID);
  1194. if (QDF_IS_STATUS_ERROR(status)) {
  1195. WMI_LOGE(FL("Failed to send get SAR limit cmd: %d"), status);
  1196. wmi_buf_free(wmi_buf);
  1197. }
  1198. WMI_LOGD(FL("Exit"));
  1199. return status;
  1200. }
  1201. /**
  1202. * wmi_sar2_result_string() - return string conversion of sar2 result
  1203. * @result: sar2 result value
  1204. *
  1205. * This utility function helps log string conversion of sar2 result.
  1206. *
  1207. * Return: string conversion of sar 2 result, if match found;
  1208. * "Unknown response" otherwise.
  1209. */
  1210. static const char *wmi_sar2_result_string(uint32_t result)
  1211. {
  1212. switch (result) {
  1213. CASE_RETURN_STRING(WMI_SAR2_SUCCESS);
  1214. CASE_RETURN_STRING(WMI_SAR2_INVALID_ANTENNA_INDEX);
  1215. CASE_RETURN_STRING(WMI_SAR2_INVALID_TABLE_INDEX);
  1216. CASE_RETURN_STRING(WMI_SAR2_STATE_ERROR);
  1217. CASE_RETURN_STRING(WMI_SAR2_BDF_NO_TABLE);
  1218. default:
  1219. return "Unknown response";
  1220. }
  1221. }
  1222. /**
  1223. * extract_sar2_result_event_tlv() - process sar response event from FW.
  1224. * @handle: wma handle
  1225. * @event: event buffer
  1226. * @len: buffer length
  1227. *
  1228. * Return: 0 for success or error code
  1229. */
  1230. static QDF_STATUS extract_sar2_result_event_tlv(void *handle,
  1231. uint8_t *event,
  1232. uint32_t len)
  1233. {
  1234. wmi_sar2_result_event_fixed_param *sar2_fixed_param;
  1235. WMI_SAR2_RESULT_EVENTID_param_tlvs *param_buf =
  1236. (WMI_SAR2_RESULT_EVENTID_param_tlvs *)event;
  1237. if (!param_buf) {
  1238. WMI_LOGI("Invalid sar2 result event buffer");
  1239. return QDF_STATUS_E_INVAL;
  1240. }
  1241. sar2_fixed_param = param_buf->fixed_param;
  1242. if (!sar2_fixed_param) {
  1243. WMI_LOGI("Invalid sar2 result event fixed param buffer");
  1244. return QDF_STATUS_E_INVAL;
  1245. }
  1246. WMI_LOGI("SAR2 result: %s",
  1247. wmi_sar2_result_string(sar2_fixed_param->result));
  1248. return QDF_STATUS_SUCCESS;
  1249. }
  1250. static QDF_STATUS extract_sar_limit_event_tlv(wmi_unified_t wmi_handle,
  1251. uint8_t *evt_buf,
  1252. struct sar_limit_event *event)
  1253. {
  1254. wmi_sar_get_limits_event_fixed_param *fixed_param;
  1255. WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *param_buf;
  1256. wmi_sar_get_limit_event_row *row_in;
  1257. struct sar_limit_event_row *row_out;
  1258. uint32_t row;
  1259. if (!evt_buf) {
  1260. WMI_LOGE(FL("input event is NULL"));
  1261. return QDF_STATUS_E_INVAL;
  1262. }
  1263. if (!event) {
  1264. WMI_LOGE(FL("output event is NULL"));
  1265. return QDF_STATUS_E_INVAL;
  1266. }
  1267. param_buf = (WMI_SAR_GET_LIMITS_EVENTID_param_tlvs *)evt_buf;
  1268. fixed_param = param_buf->fixed_param;
  1269. if (!fixed_param) {
  1270. WMI_LOGE(FL("Invalid fixed param"));
  1271. return QDF_STATUS_E_INVAL;
  1272. }
  1273. event->sar_enable = fixed_param->sar_enable;
  1274. event->num_limit_rows = fixed_param->num_limit_rows;
  1275. if (event->num_limit_rows > param_buf->num_sar_get_limits) {
  1276. WMI_LOGE(FL("Num rows %d exceeds sar_get_limits rows len %d"),
  1277. event->num_limit_rows, param_buf->num_sar_get_limits);
  1278. return QDF_STATUS_E_INVAL;
  1279. }
  1280. if (event->num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
  1281. QDF_ASSERT(0);
  1282. WMI_LOGE(FL("Num rows %d exceeds max of %d"),
  1283. event->num_limit_rows,
  1284. MAX_SAR_LIMIT_ROWS_SUPPORTED);
  1285. event->num_limit_rows = MAX_SAR_LIMIT_ROWS_SUPPORTED;
  1286. }
  1287. row_in = param_buf->sar_get_limits;
  1288. if (!row_in) {
  1289. WMI_LOGD("sar_get_limits is NULL");
  1290. } else {
  1291. row_out = &event->sar_limit_row[0];
  1292. for (row = 0; row < event->num_limit_rows; row++) {
  1293. row_out->band_id = row_in->band_id;
  1294. row_out->chain_id = row_in->chain_id;
  1295. row_out->mod_id = row_in->mod_id;
  1296. row_out->limit_value = row_in->limit_value;
  1297. row_out++;
  1298. row_in++;
  1299. }
  1300. }
  1301. return QDF_STATUS_SUCCESS;
  1302. }
  1303. /**
  1304. * send_set_del_pmkid_cache_cmd_tlv() - send wmi cmd of set del pmkid
  1305. * @wmi_handle: wmi handler
  1306. * @pmk_info: pointer to PMK cache entry
  1307. * @vdev_id: vdev id
  1308. *
  1309. * Return: 0 for success and non zero for failure
  1310. */
  1311. static QDF_STATUS send_set_del_pmkid_cache_cmd_tlv(wmi_unified_t wmi_handle,
  1312. struct wmi_unified_pmk_cache *pmk_info)
  1313. {
  1314. wmi_pdev_update_pmk_cache_cmd_fixed_param *cmd;
  1315. wmi_buf_t buf;
  1316. QDF_STATUS status;
  1317. uint8_t *buf_ptr;
  1318. wmi_pmk_cache *pmksa;
  1319. uint32_t len = sizeof(*cmd);
  1320. if (pmk_info->pmk_len)
  1321. len += WMI_TLV_HDR_SIZE + sizeof(*pmksa);
  1322. buf = wmi_buf_alloc(wmi_handle, len);
  1323. if (!buf) {
  1324. return QDF_STATUS_E_NOMEM;
  1325. }
  1326. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1327. cmd = (wmi_pdev_update_pmk_cache_cmd_fixed_param *) buf_ptr;
  1328. WMITLV_SET_HDR(&cmd->tlv_header,
  1329. WMITLV_TAG_STRUC_wmi_pdev_update_pmk_cache_cmd_fixed_param,
  1330. WMITLV_GET_STRUCT_TLVLEN(
  1331. wmi_pdev_update_pmk_cache_cmd_fixed_param));
  1332. cmd->vdev_id = pmk_info->vdev_id;
  1333. /* If pmk_info->pmk_len is 0, this is a flush request */
  1334. if (!pmk_info->pmk_len) {
  1335. cmd->op_flag = WMI_PMK_CACHE_OP_FLAG_FLUSH_ALL;
  1336. cmd->num_cache = 0;
  1337. goto send_cmd;
  1338. }
  1339. cmd->num_cache = 1;
  1340. buf_ptr += sizeof(*cmd);
  1341. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1342. sizeof(*pmksa));
  1343. buf_ptr += WMI_TLV_HDR_SIZE;
  1344. pmksa = (wmi_pmk_cache *)buf_ptr;
  1345. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_pmk_cache,
  1346. WMITLV_GET_STRUCT_TLVLEN
  1347. (wmi_pmk_cache));
  1348. pmksa->pmk_len = pmk_info->pmk_len;
  1349. qdf_mem_copy(pmksa->pmk, pmk_info->pmk, pmksa->pmk_len);
  1350. pmksa->pmkid_len = pmk_info->pmkid_len;
  1351. qdf_mem_copy(pmksa->pmkid, pmk_info->pmkid, pmksa->pmkid_len);
  1352. qdf_mem_copy(&(pmksa->bssid), &(pmk_info->bssid), sizeof(wmi_mac_addr));
  1353. pmksa->ssid.ssid_len = pmk_info->ssid.length;
  1354. qdf_mem_copy(&(pmksa->ssid.ssid), &(pmk_info->ssid.mac_ssid),
  1355. pmksa->ssid.ssid_len);
  1356. pmksa->cache_id = pmk_info->cache_id;
  1357. pmksa->cat_flag = pmk_info->cat_flag;
  1358. pmksa->action_flag = pmk_info->action_flag;
  1359. send_cmd:
  1360. wmi_mtrace(WMI_PDEV_UPDATE_PMK_CACHE_CMDID, cmd->vdev_id, 0);
  1361. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  1362. WMI_PDEV_UPDATE_PMK_CACHE_CMDID);
  1363. if (status != QDF_STATUS_SUCCESS) {
  1364. WMI_LOGE("%s: failed to send set del pmkid cache command %d",
  1365. __func__, status);
  1366. wmi_buf_free(buf);
  1367. }
  1368. return status;
  1369. }
  1370. /**
  1371. * send_del_ts_cmd_tlv() - send DELTS request to fw
  1372. * @wmi_handle: wmi handle
  1373. * @msg: delts params
  1374. *
  1375. * Return: CDF status
  1376. */
  1377. static QDF_STATUS send_del_ts_cmd_tlv(wmi_unified_t wmi_handle, uint8_t vdev_id,
  1378. uint8_t ac)
  1379. {
  1380. wmi_vdev_wmm_delts_cmd_fixed_param *cmd;
  1381. wmi_buf_t buf;
  1382. int32_t len = sizeof(*cmd);
  1383. buf = wmi_buf_alloc(wmi_handle, len);
  1384. if (!buf) {
  1385. return QDF_STATUS_E_NOMEM;
  1386. }
  1387. cmd = (wmi_vdev_wmm_delts_cmd_fixed_param *) wmi_buf_data(buf);
  1388. WMITLV_SET_HDR(&cmd->tlv_header,
  1389. WMITLV_TAG_STRUC_wmi_vdev_wmm_delts_cmd_fixed_param,
  1390. WMITLV_GET_STRUCT_TLVLEN
  1391. (wmi_vdev_wmm_delts_cmd_fixed_param));
  1392. cmd->vdev_id = vdev_id;
  1393. cmd->ac = ac;
  1394. WMI_LOGD("Delts vdev:%d, ac:%d, %s:%d",
  1395. cmd->vdev_id, cmd->ac, __func__, __LINE__);
  1396. wmi_mtrace(WMI_VDEV_WMM_DELTS_CMDID, cmd->vdev_id, 0);
  1397. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1398. WMI_VDEV_WMM_DELTS_CMDID)) {
  1399. WMI_LOGP("%s: Failed to send vdev DELTS command", __func__);
  1400. wmi_buf_free(buf);
  1401. return QDF_STATUS_E_FAILURE;
  1402. }
  1403. return QDF_STATUS_SUCCESS;
  1404. }
  1405. /**
  1406. * send_aggr_qos_cmd_tlv() - send aggr qos request to fw
  1407. * @wmi_handle: handle to wmi
  1408. * @aggr_qos_rsp_msg - combined struct for all ADD_TS requests.
  1409. *
  1410. * A function to handle WMI_AGGR_QOS_REQ. This will send out
  1411. * ADD_TS requestes to firmware in loop for all the ACs with
  1412. * active flow.
  1413. *
  1414. * Return: CDF status
  1415. */
  1416. static QDF_STATUS send_aggr_qos_cmd_tlv(wmi_unified_t wmi_handle,
  1417. struct aggr_add_ts_param *aggr_qos_rsp_msg)
  1418. {
  1419. int i = 0;
  1420. wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
  1421. wmi_buf_t buf;
  1422. int32_t len = sizeof(*cmd);
  1423. for (i = 0; i < WMI_QOS_NUM_AC_MAX; i++) {
  1424. /* if flow in this AC is active */
  1425. if (((1 << i) & aggr_qos_rsp_msg->tspecIdx)) {
  1426. /*
  1427. * as per implementation of wma_add_ts_req() we
  1428. * are not waiting any response from firmware so
  1429. * apart from sending ADDTS to firmware just send
  1430. * success to upper layers
  1431. */
  1432. aggr_qos_rsp_msg->status[i] = QDF_STATUS_SUCCESS;
  1433. buf = wmi_buf_alloc(wmi_handle, len);
  1434. if (!buf) {
  1435. return QDF_STATUS_E_NOMEM;
  1436. }
  1437. cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *)
  1438. wmi_buf_data(buf);
  1439. WMITLV_SET_HDR(&cmd->tlv_header,
  1440. WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
  1441. WMITLV_GET_STRUCT_TLVLEN
  1442. (wmi_vdev_wmm_addts_cmd_fixed_param));
  1443. cmd->vdev_id = aggr_qos_rsp_msg->vdev_id;
  1444. cmd->ac =
  1445. WMI_TID_TO_AC(aggr_qos_rsp_msg->tspec[i].tsinfo.
  1446. traffic.userPrio);
  1447. cmd->medium_time_us =
  1448. aggr_qos_rsp_msg->tspec[i].mediumTime * 32;
  1449. cmd->downgrade_type = WMM_AC_DOWNGRADE_DEPRIO;
  1450. WMI_LOGD("%s:%d: Addts vdev:%d, ac:%d, mediumTime:%d downgrade_type:%d",
  1451. __func__, __LINE__, cmd->vdev_id, cmd->ac,
  1452. cmd->medium_time_us, cmd->downgrade_type);
  1453. wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
  1454. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1455. WMI_VDEV_WMM_ADDTS_CMDID)) {
  1456. WMI_LOGP("%s: Failed to send vdev ADDTS command",
  1457. __func__);
  1458. aggr_qos_rsp_msg->status[i] =
  1459. QDF_STATUS_E_FAILURE;
  1460. wmi_buf_free(buf);
  1461. return QDF_STATUS_E_FAILURE;
  1462. }
  1463. }
  1464. }
  1465. return QDF_STATUS_SUCCESS;
  1466. }
  1467. /**
  1468. * send_add_ts_cmd_tlv() - send ADDTS request to fw
  1469. * @wmi_handle: wmi handle
  1470. * @msg: ADDTS params
  1471. *
  1472. * Return: CDF status
  1473. */
  1474. static QDF_STATUS send_add_ts_cmd_tlv(wmi_unified_t wmi_handle,
  1475. struct add_ts_param *msg)
  1476. {
  1477. wmi_vdev_wmm_addts_cmd_fixed_param *cmd;
  1478. wmi_buf_t buf;
  1479. int32_t len = sizeof(*cmd);
  1480. msg->status = QDF_STATUS_SUCCESS;
  1481. buf = wmi_buf_alloc(wmi_handle, len);
  1482. if (!buf) {
  1483. return QDF_STATUS_E_NOMEM;
  1484. }
  1485. cmd = (wmi_vdev_wmm_addts_cmd_fixed_param *) wmi_buf_data(buf);
  1486. WMITLV_SET_HDR(&cmd->tlv_header,
  1487. WMITLV_TAG_STRUC_wmi_vdev_wmm_addts_cmd_fixed_param,
  1488. WMITLV_GET_STRUCT_TLVLEN
  1489. (wmi_vdev_wmm_addts_cmd_fixed_param));
  1490. cmd->vdev_id = msg->sme_session_id;
  1491. cmd->ac = msg->tspec.tsinfo.traffic.userPrio;
  1492. cmd->medium_time_us = msg->tspec.mediumTime * 32;
  1493. cmd->downgrade_type = WMM_AC_DOWNGRADE_DROP;
  1494. WMI_LOGD("Addts vdev:%d, ac:%d, mediumTime:%d, downgrade_type:%d %s:%d",
  1495. cmd->vdev_id, cmd->ac, cmd->medium_time_us,
  1496. cmd->downgrade_type, __func__, __LINE__);
  1497. wmi_mtrace(WMI_VDEV_WMM_ADDTS_CMDID, cmd->vdev_id, 0);
  1498. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1499. WMI_VDEV_WMM_ADDTS_CMDID)) {
  1500. WMI_LOGP("%s: Failed to send vdev ADDTS command", __func__);
  1501. msg->status = QDF_STATUS_E_FAILURE;
  1502. wmi_buf_free(buf);
  1503. return QDF_STATUS_E_FAILURE;
  1504. }
  1505. return QDF_STATUS_SUCCESS;
  1506. }
  1507. /**
  1508. * send_process_add_periodic_tx_ptrn_cmd_tlv - add periodic tx ptrn
  1509. * @wmi_handle: wmi handle
  1510. * @pAddPeriodicTxPtrnParams: tx ptrn params
  1511. *
  1512. * Retrun: CDF status
  1513. */
  1514. static QDF_STATUS send_process_add_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
  1515. struct periodic_tx_pattern *
  1516. pAddPeriodicTxPtrnParams,
  1517. uint8_t vdev_id)
  1518. {
  1519. WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
  1520. wmi_buf_t wmi_buf;
  1521. uint32_t len;
  1522. uint8_t *buf_ptr;
  1523. uint32_t ptrn_len, ptrn_len_aligned;
  1524. int j;
  1525. ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize;
  1526. ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t));
  1527. len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) +
  1528. WMI_TLV_HDR_SIZE + ptrn_len_aligned;
  1529. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  1530. if (!wmi_buf) {
  1531. return QDF_STATUS_E_NOMEM;
  1532. }
  1533. buf_ptr = (uint8_t *) wmi_buf_data(wmi_buf);
  1534. cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *) buf_ptr;
  1535. WMITLV_SET_HDR(&cmd->tlv_header,
  1536. WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
  1537. WMITLV_GET_STRUCT_TLVLEN
  1538. (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
  1539. /* Pass the pattern id to delete for the corresponding vdev id */
  1540. cmd->vdev_id = vdev_id;
  1541. cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId;
  1542. cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs;
  1543. cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize;
  1544. /* Pattern info */
  1545. buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
  1546. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned);
  1547. buf_ptr += WMI_TLV_HDR_SIZE;
  1548. qdf_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, ptrn_len);
  1549. for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++)
  1550. WMI_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff);
  1551. WMI_LOGD("%s: Add ptrn id: %d vdev_id: %d",
  1552. __func__, cmd->pattern_id, cmd->vdev_id);
  1553. wmi_mtrace(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
  1554. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  1555. WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
  1556. WMI_LOGE("%s: failed to add pattern set state command",
  1557. __func__);
  1558. wmi_buf_free(wmi_buf);
  1559. return QDF_STATUS_E_FAILURE;
  1560. }
  1561. return QDF_STATUS_SUCCESS;
  1562. }
  1563. /**
  1564. * send_process_del_periodic_tx_ptrn_cmd_tlv - del periodic tx ptrn
  1565. * @wmi_handle: wmi handle
  1566. * @vdev_id: vdev id
  1567. * @pattern_id: pattern id
  1568. *
  1569. * Retrun: CDF status
  1570. */
  1571. static QDF_STATUS send_process_del_periodic_tx_ptrn_cmd_tlv(wmi_unified_t wmi_handle,
  1572. uint8_t vdev_id,
  1573. uint8_t pattern_id)
  1574. {
  1575. WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *cmd;
  1576. wmi_buf_t wmi_buf;
  1577. uint32_t len =
  1578. sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param);
  1579. wmi_buf = wmi_buf_alloc(wmi_handle, len);
  1580. if (!wmi_buf) {
  1581. return QDF_STATUS_E_NOMEM;
  1582. }
  1583. cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)
  1584. wmi_buf_data(wmi_buf);
  1585. WMITLV_SET_HDR(&cmd->tlv_header,
  1586. WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param,
  1587. WMITLV_GET_STRUCT_TLVLEN
  1588. (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param));
  1589. /* Pass the pattern id to delete for the corresponding vdev id */
  1590. cmd->vdev_id = vdev_id;
  1591. cmd->pattern_id = pattern_id;
  1592. WMI_LOGD("%s: Del ptrn id: %d vdev_id: %d",
  1593. __func__, cmd->pattern_id, cmd->vdev_id);
  1594. wmi_mtrace(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, cmd->vdev_id, 0);
  1595. if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
  1596. WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) {
  1597. WMI_LOGE("%s: failed to send del pattern command", __func__);
  1598. wmi_buf_free(wmi_buf);
  1599. return QDF_STATUS_E_FAILURE;
  1600. }
  1601. return QDF_STATUS_SUCCESS;
  1602. }
  1603. /**
  1604. * send_set_auto_shutdown_timer_cmd_tlv() - sets auto shutdown timer in firmware
  1605. * @wmi_handle: wmi handle
  1606. * @timer_val: auto shutdown timer value
  1607. *
  1608. * Return: CDF status
  1609. */
  1610. static QDF_STATUS send_set_auto_shutdown_timer_cmd_tlv(wmi_unified_t wmi_handle,
  1611. uint32_t timer_val)
  1612. {
  1613. QDF_STATUS status;
  1614. wmi_buf_t buf = NULL;
  1615. uint8_t *buf_ptr;
  1616. wmi_host_auto_shutdown_cfg_cmd_fixed_param *wmi_auto_sh_cmd;
  1617. int len = sizeof(wmi_host_auto_shutdown_cfg_cmd_fixed_param);
  1618. WMI_LOGD("%s: Set WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID:TIMER_VAL=%d",
  1619. __func__, timer_val);
  1620. buf = wmi_buf_alloc(wmi_handle, len);
  1621. if (!buf) {
  1622. return QDF_STATUS_E_NOMEM;
  1623. }
  1624. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1625. wmi_auto_sh_cmd =
  1626. (wmi_host_auto_shutdown_cfg_cmd_fixed_param *) buf_ptr;
  1627. wmi_auto_sh_cmd->timer_value = timer_val;
  1628. WMITLV_SET_HDR(&wmi_auto_sh_cmd->tlv_header,
  1629. WMITLV_TAG_STRUC_wmi_host_auto_shutdown_cfg_cmd_fixed_param,
  1630. WMITLV_GET_STRUCT_TLVLEN
  1631. (wmi_host_auto_shutdown_cfg_cmd_fixed_param));
  1632. wmi_mtrace(WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID, NO_SESSION, 0);
  1633. status = wmi_unified_cmd_send(wmi_handle, buf,
  1634. len, WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID);
  1635. if (QDF_IS_STATUS_ERROR(status)) {
  1636. WMI_LOGE("%s: WMI_HOST_AUTO_SHUTDOWN_CFG_CMDID Err %d",
  1637. __func__, status);
  1638. wmi_buf_free(buf);
  1639. }
  1640. return status;
  1641. }
  1642. /**
  1643. * send_set_led_flashing_cmd_tlv() - set led flashing in fw
  1644. * @wmi_handle: wmi handle
  1645. * @flashing: flashing request
  1646. *
  1647. * Return: CDF status
  1648. */
  1649. static QDF_STATUS send_set_led_flashing_cmd_tlv(wmi_unified_t wmi_handle,
  1650. struct flashing_req_params *flashing)
  1651. {
  1652. wmi_set_led_flashing_cmd_fixed_param *cmd;
  1653. QDF_STATUS status;
  1654. wmi_buf_t buf;
  1655. uint8_t *buf_ptr;
  1656. int32_t len = sizeof(wmi_set_led_flashing_cmd_fixed_param);
  1657. buf = wmi_buf_alloc(wmi_handle, len);
  1658. if (!buf) {
  1659. return QDF_STATUS_E_NOMEM;
  1660. }
  1661. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1662. cmd = (wmi_set_led_flashing_cmd_fixed_param *) buf_ptr;
  1663. WMITLV_SET_HDR(&cmd->tlv_header,
  1664. WMITLV_TAG_STRUC_wmi_set_led_flashing_cmd_fixed_param,
  1665. WMITLV_GET_STRUCT_TLVLEN
  1666. (wmi_set_led_flashing_cmd_fixed_param));
  1667. cmd->pattern_id = flashing->pattern_id;
  1668. cmd->led_x0 = flashing->led_x0;
  1669. cmd->led_x1 = flashing->led_x1;
  1670. wmi_mtrace(WMI_PDEV_SET_LED_FLASHING_CMDID, NO_SESSION, 0);
  1671. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  1672. WMI_PDEV_SET_LED_FLASHING_CMDID);
  1673. if (QDF_IS_STATUS_ERROR(status)) {
  1674. WMI_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD"
  1675. " returned Error %d", __func__, status);
  1676. wmi_buf_free(buf);
  1677. }
  1678. return status;
  1679. }
  1680. /**
  1681. * send_process_ch_avoid_update_cmd_tlv() - handles channel avoid update request
  1682. * @wmi_handle: wmi handle
  1683. * @ch_avoid_update_req: channel avoid update params
  1684. *
  1685. * Return: CDF status
  1686. */
  1687. static QDF_STATUS send_process_ch_avoid_update_cmd_tlv(wmi_unified_t wmi_handle)
  1688. {
  1689. QDF_STATUS status;
  1690. wmi_buf_t buf = NULL;
  1691. uint8_t *buf_ptr;
  1692. wmi_chan_avoid_update_cmd_param *ch_avoid_update_fp;
  1693. int len = sizeof(wmi_chan_avoid_update_cmd_param);
  1694. buf = wmi_buf_alloc(wmi_handle, len);
  1695. if (!buf) {
  1696. return QDF_STATUS_E_NOMEM;
  1697. }
  1698. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1699. ch_avoid_update_fp = (wmi_chan_avoid_update_cmd_param *) buf_ptr;
  1700. WMITLV_SET_HDR(&ch_avoid_update_fp->tlv_header,
  1701. WMITLV_TAG_STRUC_wmi_chan_avoid_update_cmd_param,
  1702. WMITLV_GET_STRUCT_TLVLEN
  1703. (wmi_chan_avoid_update_cmd_param));
  1704. wmi_mtrace(WMI_CHAN_AVOID_UPDATE_CMDID, NO_SESSION, 0);
  1705. status = wmi_unified_cmd_send(wmi_handle, buf,
  1706. len, WMI_CHAN_AVOID_UPDATE_CMDID);
  1707. if (QDF_IS_STATUS_ERROR(status)) {
  1708. WMI_LOGE("wmi_unified_cmd_send"
  1709. " WMITLV_TABLE_WMI_CHAN_AVOID_UPDATE"
  1710. " returned Error %d", status);
  1711. wmi_buf_free(buf);
  1712. }
  1713. return status;
  1714. }
  1715. /**
  1716. * send_pdev_set_pcl_cmd_tlv() - Send WMI_SOC_SET_PCL_CMDID to FW
  1717. * @wmi_handle: wmi handle
  1718. * @msg: PCL structure containing the PCL and the number of channels
  1719. *
  1720. * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
  1721. * firmware. The DBS Manager is the consumer of this information in the WLAN
  1722. * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
  1723. * to migrate to a new channel without host driver involvement. An example of
  1724. * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
  1725. * manage the channel selection without firmware involvement.
  1726. *
  1727. * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
  1728. * channel list. The weights corresponds to the channels sent in
  1729. * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
  1730. * weightage compared to the non PCL channels.
  1731. *
  1732. * Return: Success if the cmd is sent successfully to the firmware
  1733. */
  1734. static QDF_STATUS send_pdev_set_pcl_cmd_tlv(wmi_unified_t wmi_handle,
  1735. struct wmi_pcl_chan_weights *msg)
  1736. {
  1737. wmi_pdev_set_pcl_cmd_fixed_param *cmd;
  1738. wmi_buf_t buf;
  1739. uint8_t *buf_ptr;
  1740. uint32_t *cmd_args, i, len;
  1741. uint32_t chan_len;
  1742. chan_len = msg->saved_num_chan;
  1743. len = sizeof(*cmd) +
  1744. WMI_TLV_HDR_SIZE + (chan_len * sizeof(uint32_t));
  1745. buf = wmi_buf_alloc(wmi_handle, len);
  1746. if (!buf) {
  1747. return QDF_STATUS_E_NOMEM;
  1748. }
  1749. cmd = (wmi_pdev_set_pcl_cmd_fixed_param *) wmi_buf_data(buf);
  1750. buf_ptr = (uint8_t *) cmd;
  1751. WMITLV_SET_HDR(&cmd->tlv_header,
  1752. WMITLV_TAG_STRUC_wmi_pdev_set_pcl_cmd_fixed_param,
  1753. WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_pcl_cmd_fixed_param));
  1754. cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
  1755. WMI_HOST_PDEV_ID_SOC);
  1756. cmd->num_chan = chan_len;
  1757. WMI_LOGD("%s: Total chan (PCL) len:%d", __func__, cmd->num_chan);
  1758. buf_ptr += sizeof(wmi_pdev_set_pcl_cmd_fixed_param);
  1759. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
  1760. (chan_len * sizeof(uint32_t)));
  1761. cmd_args = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
  1762. for (i = 0; i < chan_len ; i++) {
  1763. cmd_args[i] = msg->weighed_valid_list[i];
  1764. WMI_LOGD("%s: chan:%d weight:%d", __func__,
  1765. msg->saved_chan_list[i], cmd_args[i]);
  1766. }
  1767. wmi_mtrace(WMI_PDEV_SET_PCL_CMDID, NO_SESSION, 0);
  1768. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1769. WMI_PDEV_SET_PCL_CMDID)) {
  1770. WMI_LOGE("%s: Failed to send WMI_PDEV_SET_PCL_CMDID", __func__);
  1771. wmi_buf_free(buf);
  1772. return QDF_STATUS_E_FAILURE;
  1773. }
  1774. return QDF_STATUS_SUCCESS;
  1775. }
  1776. /**
  1777. * send_pdev_set_hw_mode_cmd_tlv() - Send WMI_PDEV_SET_HW_MODE_CMDID to FW
  1778. * @wmi_handle: wmi handle
  1779. * @msg: Structure containing the following parameters
  1780. *
  1781. * - hw_mode_index: The HW_Mode field is a enumerated type that is selected
  1782. * from the HW_Mode table, which is returned in the WMI_SERVICE_READY_EVENTID.
  1783. *
  1784. * Provides notification to the WLAN firmware that host driver is requesting a
  1785. * HardWare (HW) Mode change. This command is needed to support iHelium in the
  1786. * configurations that include the Dual Band Simultaneous (DBS) feature.
  1787. *
  1788. * Return: Success if the cmd is sent successfully to the firmware
  1789. */
  1790. static QDF_STATUS send_pdev_set_hw_mode_cmd_tlv(wmi_unified_t wmi_handle,
  1791. uint32_t hw_mode_index)
  1792. {
  1793. wmi_pdev_set_hw_mode_cmd_fixed_param *cmd;
  1794. wmi_buf_t buf;
  1795. uint32_t len;
  1796. len = sizeof(*cmd);
  1797. buf = wmi_buf_alloc(wmi_handle, len);
  1798. if (!buf) {
  1799. return QDF_STATUS_E_NOMEM;
  1800. }
  1801. cmd = (wmi_pdev_set_hw_mode_cmd_fixed_param *) wmi_buf_data(buf);
  1802. WMITLV_SET_HDR(&cmd->tlv_header,
  1803. WMITLV_TAG_STRUC_wmi_pdev_set_hw_mode_cmd_fixed_param,
  1804. WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_set_hw_mode_cmd_fixed_param));
  1805. cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
  1806. WMI_HOST_PDEV_ID_SOC);
  1807. cmd->hw_mode_index = hw_mode_index;
  1808. WMI_LOGI("%s: HW mode index:%d", __func__, cmd->hw_mode_index);
  1809. wmi_mtrace(WMI_PDEV_SET_HW_MODE_CMDID, NO_SESSION, 0);
  1810. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1811. WMI_PDEV_SET_HW_MODE_CMDID)) {
  1812. WMI_LOGE("%s: Failed to send WMI_PDEV_SET_HW_MODE_CMDID",
  1813. __func__);
  1814. wmi_buf_free(buf);
  1815. return QDF_STATUS_E_FAILURE;
  1816. }
  1817. return QDF_STATUS_SUCCESS;
  1818. }
  1819. #ifdef WLAN_POLICY_MGR_ENABLE
  1820. /**
  1821. * send_pdev_set_dual_mac_config_cmd_tlv() - Set dual mac config to FW
  1822. * @wmi_handle: wmi handle
  1823. * @msg: Dual MAC config parameters
  1824. *
  1825. * Configures WLAN firmware with the dual MAC features
  1826. *
  1827. * Return: QDF_STATUS. 0 on success.
  1828. */
  1829. static
  1830. QDF_STATUS send_pdev_set_dual_mac_config_cmd_tlv(wmi_unified_t wmi_handle,
  1831. struct policy_mgr_dual_mac_config *msg)
  1832. {
  1833. wmi_pdev_set_mac_config_cmd_fixed_param *cmd;
  1834. wmi_buf_t buf;
  1835. uint32_t len;
  1836. len = sizeof(*cmd);
  1837. buf = wmi_buf_alloc(wmi_handle, len);
  1838. if (!buf) {
  1839. return QDF_STATUS_E_FAILURE;
  1840. }
  1841. cmd = (wmi_pdev_set_mac_config_cmd_fixed_param *) wmi_buf_data(buf);
  1842. WMITLV_SET_HDR(&cmd->tlv_header,
  1843. WMITLV_TAG_STRUC_wmi_pdev_set_mac_config_cmd_fixed_param,
  1844. WMITLV_GET_STRUCT_TLVLEN(
  1845. wmi_pdev_set_mac_config_cmd_fixed_param));
  1846. cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
  1847. WMI_HOST_PDEV_ID_SOC);
  1848. cmd->concurrent_scan_config_bits = msg->scan_config;
  1849. cmd->fw_mode_config_bits = msg->fw_mode_config;
  1850. WMI_LOGD("%s: scan_config:%x fw_mode_config:%x",
  1851. __func__, msg->scan_config, msg->fw_mode_config);
  1852. wmi_mtrace(WMI_PDEV_SET_MAC_CONFIG_CMDID, NO_SESSION, 0);
  1853. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  1854. WMI_PDEV_SET_MAC_CONFIG_CMDID)) {
  1855. WMI_LOGE("%s: Failed to send WMI_PDEV_SET_MAC_CONFIG_CMDID",
  1856. __func__);
  1857. wmi_buf_free(buf);
  1858. return QDF_STATUS_E_FAILURE;
  1859. }
  1860. return QDF_STATUS_SUCCESS;
  1861. }
  1862. void wmi_policy_mgr_attach_tlv(struct wmi_unified *wmi_handle)
  1863. {
  1864. struct wmi_ops *ops = wmi_handle->ops;
  1865. ops->send_pdev_set_dual_mac_config_cmd =
  1866. send_pdev_set_dual_mac_config_cmd_tlv;
  1867. }
  1868. #endif /* WLAN_POLICY_MGR_ENABLE */
  1869. /**
  1870. * send_adapt_dwelltime_params_cmd_tlv() - send wmi cmd of adaptive dwelltime
  1871. * configuration params
  1872. * @wma_handle: wma handler
  1873. * @dwelltime_params: pointer to dwelltime_params
  1874. *
  1875. * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
  1876. */
  1877. static
  1878. QDF_STATUS send_adapt_dwelltime_params_cmd_tlv(wmi_unified_t wmi_handle,
  1879. struct wmi_adaptive_dwelltime_params *dwelltime_params)
  1880. {
  1881. wmi_scan_adaptive_dwell_config_fixed_param *dwell_param;
  1882. wmi_scan_adaptive_dwell_parameters_tlv *cmd;
  1883. wmi_buf_t buf;
  1884. uint8_t *buf_ptr;
  1885. int32_t err;
  1886. int len;
  1887. len = sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
  1888. len += WMI_TLV_HDR_SIZE; /* TLV for ext_thresholds*/
  1889. len += sizeof(wmi_scan_adaptive_dwell_parameters_tlv);
  1890. buf = wmi_buf_alloc(wmi_handle, len);
  1891. if (!buf) {
  1892. return QDF_STATUS_E_NOMEM;
  1893. }
  1894. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1895. dwell_param = (wmi_scan_adaptive_dwell_config_fixed_param *) buf_ptr;
  1896. WMITLV_SET_HDR(&dwell_param->tlv_header,
  1897. WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_config_fixed_param,
  1898. WMITLV_GET_STRUCT_TLVLEN
  1899. (wmi_scan_adaptive_dwell_config_fixed_param));
  1900. dwell_param->enable = dwelltime_params->is_enabled;
  1901. buf_ptr += sizeof(wmi_scan_adaptive_dwell_config_fixed_param);
  1902. WMITLV_SET_HDR(buf_ptr,
  1903. WMITLV_TAG_ARRAY_STRUC,
  1904. sizeof(wmi_scan_adaptive_dwell_parameters_tlv));
  1905. buf_ptr += WMI_TLV_HDR_SIZE;
  1906. cmd = (wmi_scan_adaptive_dwell_parameters_tlv *) buf_ptr;
  1907. WMITLV_SET_HDR(&cmd->tlv_header,
  1908. WMITLV_TAG_STRUC_wmi_scan_adaptive_dwell_parameters_tlv,
  1909. WMITLV_GET_STRUCT_TLVLEN(
  1910. wmi_scan_adaptive_dwell_parameters_tlv));
  1911. cmd->default_adaptive_dwell_mode = dwelltime_params->dwelltime_mode;
  1912. cmd->adapative_lpf_weight = dwelltime_params->lpf_weight;
  1913. cmd->passive_monitor_interval_ms = dwelltime_params->passive_mon_intval;
  1914. cmd->wifi_activity_threshold_pct = dwelltime_params->wifi_act_threshold;
  1915. wmi_mtrace(WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID, NO_SESSION, 0);
  1916. err = wmi_unified_cmd_send(wmi_handle, buf,
  1917. len, WMI_SCAN_ADAPTIVE_DWELL_CONFIG_CMDID);
  1918. if (err) {
  1919. WMI_LOGE("Failed to send adapt dwelltime cmd err=%d", err);
  1920. wmi_buf_free(buf);
  1921. return QDF_STATUS_E_FAILURE;
  1922. }
  1923. return QDF_STATUS_SUCCESS;
  1924. }
  1925. /**
  1926. * send_dbs_scan_sel_params_cmd_tlv() - send wmi cmd of DBS scan selection
  1927. * configuration params
  1928. * @wmi_handle: wmi handler
  1929. * @dbs_scan_params: pointer to wmi_dbs_scan_sel_params
  1930. *
  1931. * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
  1932. */
  1933. static QDF_STATUS send_dbs_scan_sel_params_cmd_tlv(wmi_unified_t wmi_handle,
  1934. struct wmi_dbs_scan_sel_params *dbs_scan_params)
  1935. {
  1936. wmi_scan_dbs_duty_cycle_fixed_param *dbs_scan_param;
  1937. wmi_scan_dbs_duty_cycle_tlv_param *cmd;
  1938. wmi_buf_t buf;
  1939. uint8_t *buf_ptr;
  1940. QDF_STATUS err;
  1941. uint32_t i;
  1942. int len;
  1943. len = sizeof(*dbs_scan_param);
  1944. len += WMI_TLV_HDR_SIZE;
  1945. len += dbs_scan_params->num_clients * sizeof(*cmd);
  1946. buf = wmi_buf_alloc(wmi_handle, len);
  1947. if (!buf) {
  1948. return QDF_STATUS_E_NOMEM;
  1949. }
  1950. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  1951. dbs_scan_param = (wmi_scan_dbs_duty_cycle_fixed_param *) buf_ptr;
  1952. WMITLV_SET_HDR(&dbs_scan_param->tlv_header,
  1953. WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_fixed_param,
  1954. WMITLV_GET_STRUCT_TLVLEN
  1955. (wmi_scan_dbs_duty_cycle_fixed_param));
  1956. dbs_scan_param->num_clients = dbs_scan_params->num_clients;
  1957. dbs_scan_param->pdev_id = dbs_scan_params->pdev_id;
  1958. buf_ptr += sizeof(*dbs_scan_param);
  1959. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  1960. (sizeof(*cmd) * dbs_scan_params->num_clients));
  1961. buf_ptr = buf_ptr + (uint8_t) WMI_TLV_HDR_SIZE;
  1962. for (i = 0; i < dbs_scan_params->num_clients; i++) {
  1963. cmd = (wmi_scan_dbs_duty_cycle_tlv_param *) buf_ptr;
  1964. WMITLV_SET_HDR(&cmd->tlv_header,
  1965. WMITLV_TAG_STRUC_wmi_scan_dbs_duty_cycle_param_tlv,
  1966. WMITLV_GET_STRUCT_TLVLEN(
  1967. wmi_scan_dbs_duty_cycle_tlv_param));
  1968. cmd->module_id = dbs_scan_params->module_id[i];
  1969. cmd->num_dbs_scans = dbs_scan_params->num_dbs_scans[i];
  1970. cmd->num_non_dbs_scans = dbs_scan_params->num_non_dbs_scans[i];
  1971. buf_ptr = buf_ptr + (uint8_t) sizeof(*cmd);
  1972. }
  1973. wmi_mtrace(WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID, NO_SESSION, 0);
  1974. err = wmi_unified_cmd_send(wmi_handle, buf,
  1975. len, WMI_SET_SCAN_DBS_DUTY_CYCLE_CMDID);
  1976. if (QDF_IS_STATUS_ERROR(err)) {
  1977. WMI_LOGE("Failed to send dbs scan selection cmd err=%d", err);
  1978. wmi_buf_free(buf);
  1979. return QDF_STATUS_E_FAILURE;
  1980. }
  1981. return QDF_STATUS_SUCCESS;
  1982. }
  1983. /**
  1984. * send_set_arp_stats_req_cmd_tlv() - send wmi cmd to set arp stats request
  1985. * @wmi_handle: wmi handler
  1986. * @req_buf: set arp stats request buffer
  1987. *
  1988. * Return: 0 for success and non zero for failure
  1989. */
  1990. static QDF_STATUS send_set_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
  1991. struct set_arp_stats *req_buf)
  1992. {
  1993. wmi_buf_t buf = NULL;
  1994. QDF_STATUS status;
  1995. int len;
  1996. uint8_t *buf_ptr;
  1997. wmi_vdev_set_arp_stats_cmd_fixed_param *wmi_set_arp;
  1998. len = sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
  1999. if (req_buf->pkt_type_bitmap) {
  2000. len += WMI_TLV_HDR_SIZE;
  2001. len += sizeof(wmi_vdev_set_connectivity_check_stats);
  2002. }
  2003. buf = wmi_buf_alloc(wmi_handle, len);
  2004. if (!buf) {
  2005. return QDF_STATUS_E_NOMEM;
  2006. }
  2007. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  2008. wmi_set_arp =
  2009. (wmi_vdev_set_arp_stats_cmd_fixed_param *) buf_ptr;
  2010. WMITLV_SET_HDR(&wmi_set_arp->tlv_header,
  2011. WMITLV_TAG_STRUC_wmi_vdev_set_arp_stats_cmd_fixed_param,
  2012. WMITLV_GET_STRUCT_TLVLEN
  2013. (wmi_vdev_set_arp_stats_cmd_fixed_param));
  2014. /* fill in per roam config values */
  2015. wmi_set_arp->vdev_id = req_buf->vdev_id;
  2016. wmi_set_arp->set_clr = req_buf->flag;
  2017. wmi_set_arp->pkt_type = req_buf->pkt_type;
  2018. wmi_set_arp->ipv4 = req_buf->ip_addr;
  2019. WMI_LOGD("NUD Stats: vdev_id %u set_clr %u pkt_type:%u ipv4 %u",
  2020. wmi_set_arp->vdev_id, wmi_set_arp->set_clr,
  2021. wmi_set_arp->pkt_type, wmi_set_arp->ipv4);
  2022. /*
  2023. * pkt_type_bitmap should be non-zero to ensure
  2024. * presence of additional stats.
  2025. */
  2026. if (req_buf->pkt_type_bitmap) {
  2027. wmi_vdev_set_connectivity_check_stats *wmi_set_connect_stats;
  2028. buf_ptr += sizeof(wmi_vdev_set_arp_stats_cmd_fixed_param);
  2029. WMITLV_SET_HDR(buf_ptr,
  2030. WMITLV_TAG_ARRAY_STRUC,
  2031. sizeof(wmi_vdev_set_connectivity_check_stats));
  2032. buf_ptr += WMI_TLV_HDR_SIZE;
  2033. wmi_set_connect_stats =
  2034. (wmi_vdev_set_connectivity_check_stats *)buf_ptr;
  2035. WMITLV_SET_HDR(&wmi_set_connect_stats->tlv_header,
  2036. WMITLV_TAG_STRUC_wmi_vdev_set_connectivity_check_stats,
  2037. WMITLV_GET_STRUCT_TLVLEN(
  2038. wmi_vdev_set_connectivity_check_stats));
  2039. wmi_set_connect_stats->pkt_type_bitmap =
  2040. req_buf->pkt_type_bitmap;
  2041. wmi_set_connect_stats->tcp_src_port = req_buf->tcp_src_port;
  2042. wmi_set_connect_stats->tcp_dst_port = req_buf->tcp_dst_port;
  2043. wmi_set_connect_stats->icmp_ipv4 = req_buf->icmp_ipv4;
  2044. WMI_LOGD("Connectivity Stats: pkt_type_bitmap %u tcp_src_port:%u tcp_dst_port %u icmp_ipv4 %u",
  2045. wmi_set_connect_stats->pkt_type_bitmap,
  2046. wmi_set_connect_stats->tcp_src_port,
  2047. wmi_set_connect_stats->tcp_dst_port,
  2048. wmi_set_connect_stats->icmp_ipv4);
  2049. }
  2050. /* Send per roam config parameters */
  2051. wmi_mtrace(WMI_VDEV_SET_ARP_STAT_CMDID, NO_SESSION, 0);
  2052. status = wmi_unified_cmd_send(wmi_handle, buf,
  2053. len, WMI_VDEV_SET_ARP_STAT_CMDID);
  2054. if (QDF_IS_STATUS_ERROR(status)) {
  2055. WMI_LOGE("WMI_SET_ARP_STATS_CMDID failed, Error %d",
  2056. status);
  2057. goto error;
  2058. }
  2059. WMI_LOGD(FL("set arp stats flag=%d, vdev=%d"),
  2060. req_buf->flag, req_buf->vdev_id);
  2061. return QDF_STATUS_SUCCESS;
  2062. error:
  2063. wmi_buf_free(buf);
  2064. return status;
  2065. }
  2066. /**
  2067. * send_get_arp_stats_req_cmd_tlv() - send wmi cmd to get arp stats request
  2068. * @wmi_handle: wmi handler
  2069. * @req_buf: get arp stats request buffer
  2070. *
  2071. * Return: 0 for success and non zero for failure
  2072. */
  2073. static QDF_STATUS send_get_arp_stats_req_cmd_tlv(wmi_unified_t wmi_handle,
  2074. struct get_arp_stats *req_buf)
  2075. {
  2076. wmi_buf_t buf = NULL;
  2077. QDF_STATUS status;
  2078. int len;
  2079. uint8_t *buf_ptr;
  2080. wmi_vdev_get_arp_stats_cmd_fixed_param *get_arp_stats;
  2081. len = sizeof(wmi_vdev_get_arp_stats_cmd_fixed_param);
  2082. buf = wmi_buf_alloc(wmi_handle, len);
  2083. if (!buf) {
  2084. return QDF_STATUS_E_NOMEM;
  2085. }
  2086. buf_ptr = (uint8_t *) wmi_buf_data(buf);
  2087. get_arp_stats =
  2088. (wmi_vdev_get_arp_stats_cmd_fixed_param *) buf_ptr;
  2089. WMITLV_SET_HDR(&get_arp_stats->tlv_header,
  2090. WMITLV_TAG_STRUC_wmi_vdev_get_arp_stats_cmd_fixed_param,
  2091. WMITLV_GET_STRUCT_TLVLEN
  2092. (wmi_vdev_get_arp_stats_cmd_fixed_param));
  2093. /* fill in arp stats req cmd values */
  2094. get_arp_stats->vdev_id = req_buf->vdev_id;
  2095. WMI_LOGI(FL("vdev=%d"), req_buf->vdev_id);
  2096. /* Send per roam config parameters */
  2097. wmi_mtrace(WMI_VDEV_GET_ARP_STAT_CMDID, NO_SESSION, 0);
  2098. status = wmi_unified_cmd_send(wmi_handle, buf,
  2099. len, WMI_VDEV_GET_ARP_STAT_CMDID);
  2100. if (QDF_IS_STATUS_ERROR(status)) {
  2101. WMI_LOGE("WMI_GET_ARP_STATS_CMDID failed, Error %d",
  2102. status);
  2103. goto error;
  2104. }
  2105. return QDF_STATUS_SUCCESS;
  2106. error:
  2107. wmi_buf_free(buf);
  2108. return status;
  2109. }
  2110. /**
  2111. * send_peer_unmap_conf_cmd_tlv() - send PEER UNMAP conf command to fw
  2112. * @wmi: wmi handle
  2113. * @vdev_id: vdev id
  2114. * @peer_id_cnt: no. of peer ids
  2115. * @peer_id_list: list of peer ids
  2116. *
  2117. * Return: QDF_STATUS_SUCCESS for success or error code
  2118. */
  2119. static QDF_STATUS send_peer_unmap_conf_cmd_tlv(wmi_unified_t wmi,
  2120. uint8_t vdev_id,
  2121. uint32_t peer_id_cnt,
  2122. uint16_t *peer_id_list)
  2123. {
  2124. int i;
  2125. wmi_buf_t buf;
  2126. uint8_t *buf_ptr;
  2127. A_UINT32 *peer_ids;
  2128. wmi_peer_unmap_response_cmd_fixed_param *cmd;
  2129. uint32_t peer_id_list_len;
  2130. uint32_t len = sizeof(*cmd);
  2131. if (!peer_id_cnt || !peer_id_list)
  2132. return QDF_STATUS_E_FAILURE;
  2133. len += WMI_TLV_HDR_SIZE;
  2134. peer_id_list_len = peer_id_cnt * sizeof(A_UINT32);
  2135. len += peer_id_list_len;
  2136. buf = wmi_buf_alloc(wmi, len);
  2137. if (!buf) {
  2138. WMI_LOGP("%s: wmi_buf_alloc failed", __func__);
  2139. return QDF_STATUS_E_NOMEM;
  2140. }
  2141. cmd = (wmi_peer_unmap_response_cmd_fixed_param *)wmi_buf_data(buf);
  2142. buf_ptr = (uint8_t *)wmi_buf_data(buf);
  2143. WMITLV_SET_HDR(&cmd->tlv_header,
  2144. WMITLV_TAG_STRUC_wmi_peer_unmap_response_cmd_fixed_param,
  2145. WMITLV_GET_STRUCT_TLVLEN
  2146. (wmi_peer_unmap_response_cmd_fixed_param));
  2147. buf_ptr += sizeof(wmi_peer_unmap_response_cmd_fixed_param);
  2148. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
  2149. peer_id_list_len);
  2150. peer_ids = (A_UINT32 *)(buf_ptr + WMI_TLV_HDR_SIZE);
  2151. for (i = 0; i < peer_id_cnt; i++)
  2152. peer_ids[i] = peer_id_list[i];
  2153. WMI_LOGD("%s: vdev_id %d peer_id_cnt %d", __func__,
  2154. vdev_id, peer_id_cnt);
  2155. wmi_mtrace(WMI_PEER_UNMAP_RESPONSE_CMDID, vdev_id, 0);
  2156. if (wmi_unified_cmd_send(wmi, buf, len,
  2157. WMI_PEER_UNMAP_RESPONSE_CMDID)) {
  2158. WMI_LOGP("%s: Failed to send peer delete conf command",
  2159. __func__);
  2160. wmi_buf_free(buf);
  2161. return QDF_STATUS_E_FAILURE;
  2162. }
  2163. return QDF_STATUS_SUCCESS;
  2164. }
  2165. void wmi_sta_attach_tlv(wmi_unified_t wmi_handle)
  2166. {
  2167. struct wmi_ops *ops = wmi_handle->ops;
  2168. ops->send_set_sta_sa_query_param_cmd =
  2169. send_set_sta_sa_query_param_cmd_tlv;
  2170. ops->send_set_sta_keep_alive_cmd = send_set_sta_keep_alive_cmd_tlv;
  2171. ops->send_vdev_set_gtx_cfg_cmd = send_vdev_set_gtx_cfg_cmd_tlv;
  2172. ops->send_process_dhcp_ind_cmd = send_process_dhcp_ind_cmd_tlv;
  2173. ops->send_get_link_speed_cmd = send_get_link_speed_cmd_tlv;
  2174. ops->send_fw_profiling_cmd = send_fw_profiling_cmd_tlv;
  2175. ops->send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv;
  2176. ops->send_wlm_latency_level_cmd = send_wlm_latency_level_cmd_tlv;
  2177. ops->send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv;
  2178. ops->send_set_base_macaddr_indicate_cmd =
  2179. send_set_base_macaddr_indicate_cmd_tlv;
  2180. ops->send_sar_limit_cmd = send_sar_limit_cmd_tlv;
  2181. ops->get_sar_limit_cmd = get_sar_limit_cmd_tlv;
  2182. ops->extract_sar_limit_event = extract_sar_limit_event_tlv;
  2183. ops->extract_sar2_result_event = extract_sar2_result_event_tlv;
  2184. ops->send_set_del_pmkid_cache_cmd = send_set_del_pmkid_cache_cmd_tlv;
  2185. ops->send_del_ts_cmd = send_del_ts_cmd_tlv;
  2186. ops->send_aggr_qos_cmd = send_aggr_qos_cmd_tlv;
  2187. ops->send_add_ts_cmd = send_add_ts_cmd_tlv;
  2188. ops->send_process_add_periodic_tx_ptrn_cmd =
  2189. send_process_add_periodic_tx_ptrn_cmd_tlv;
  2190. ops->send_process_del_periodic_tx_ptrn_cmd =
  2191. send_process_del_periodic_tx_ptrn_cmd_tlv;
  2192. ops->send_set_auto_shutdown_timer_cmd =
  2193. send_set_auto_shutdown_timer_cmd_tlv;
  2194. ops->send_set_led_flashing_cmd = send_set_led_flashing_cmd_tlv;
  2195. ops->send_process_ch_avoid_update_cmd =
  2196. send_process_ch_avoid_update_cmd_tlv;
  2197. ops->send_pdev_set_pcl_cmd = send_pdev_set_pcl_cmd_tlv;
  2198. ops->send_pdev_set_hw_mode_cmd = send_pdev_set_hw_mode_cmd_tlv;
  2199. ops->send_adapt_dwelltime_params_cmd =
  2200. send_adapt_dwelltime_params_cmd_tlv;
  2201. ops->send_dbs_scan_sel_params_cmd =
  2202. send_dbs_scan_sel_params_cmd_tlv;
  2203. ops->send_set_arp_stats_req_cmd = send_set_arp_stats_req_cmd_tlv;
  2204. ops->send_get_arp_stats_req_cmd = send_get_arp_stats_req_cmd_tlv;
  2205. ops->send_peer_unmap_conf_cmd = send_peer_unmap_conf_cmd_tlv;
  2206. wmi_tdls_attach_tlv(wmi_handle);
  2207. wmi_disa_attach_tlv(wmi_handle);
  2208. wmi_policy_mgr_attach_tlv(wmi_handle);
  2209. }