wmi_unified_vdev_tlv.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. * Copyright (c) 2016-2020 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 <qdf_module.h>
  20. #include <qdf_list.h>
  21. #include <qdf_platform.h>
  22. #include <wmi_unified_vdev_tlv.h>
  23. #include <wlan_vdev_mgr_tgt_if_tx_defs.h>
  24. static QDF_STATUS
  25. send_vdev_config_ratemask_cmd_tlv(struct wmi_unified *wmi_handle,
  26. struct config_ratemask_params *param)
  27. {
  28. wmi_vdev_config_ratemask_cmd_fixed_param *cmd;
  29. wmi_buf_t buf;
  30. int32_t len = sizeof(*cmd);
  31. buf = wmi_buf_alloc(wmi_handle, len);
  32. if (!buf) {
  33. WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
  34. return QDF_STATUS_E_FAILURE;
  35. }
  36. cmd = (wmi_vdev_config_ratemask_cmd_fixed_param *)wmi_buf_data(buf);
  37. WMITLV_SET_HDR(&cmd->tlv_header,
  38. WMITLV_TAG_STRUC_wmi_vdev_config_ratemask_fixed_param,
  39. WMITLV_GET_STRUCT_TLVLEN(
  40. wmi_vdev_config_ratemask_cmd_fixed_param));
  41. cmd->vdev_id = param->vdev_id;
  42. cmd->type = param->type;
  43. cmd->mask_lower32 = param->lower32;
  44. cmd->mask_higher32 = param->higher32;
  45. cmd->mask_lower32_2 = param->lower32_2;
  46. wmi_mtrace(WMI_VDEV_RATEMASK_CMDID, cmd->vdev_id, 0);
  47. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  48. WMI_VDEV_RATEMASK_CMDID)) {
  49. WMI_LOGE("Seting vdev ratemask failed");
  50. wmi_buf_free(buf);
  51. return QDF_STATUS_E_FAILURE;
  52. }
  53. return QDF_STATUS_SUCCESS;
  54. }
  55. static QDF_STATUS
  56. send_beacon_send_cmd_tlv(struct wmi_unified *wmi_handle,
  57. struct beacon_params *param)
  58. {
  59. QDF_STATUS ret;
  60. wmi_bcn_send_from_host_cmd_fixed_param *cmd;
  61. wmi_buf_t wmi_buf;
  62. qdf_dma_addr_t dma_addr;
  63. uint32_t dtim_flag = 0;
  64. wmi_buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd));
  65. if (!wmi_buf) {
  66. WMI_LOGE("%s : wmi_buf_alloc failed", __func__);
  67. return QDF_STATUS_E_NOMEM;
  68. }
  69. if (param->is_dtim_count_zero) {
  70. dtim_flag |= WMI_BCN_SEND_DTIM_ZERO;
  71. if (param->is_bitctl_reqd) {
  72. /* deliver CAB traffic in next DTIM beacon */
  73. dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET;
  74. }
  75. }
  76. cmd = (wmi_bcn_send_from_host_cmd_fixed_param *)wmi_buf_data(wmi_buf);
  77. WMITLV_SET_HDR(
  78. &cmd->tlv_header,
  79. WMITLV_TAG_STRUC_wmi_bcn_send_from_host_cmd_fixed_param,
  80. WMITLV_GET_STRUCT_TLVLEN
  81. (wmi_bcn_send_from_host_cmd_fixed_param));
  82. cmd->vdev_id = param->vdev_id;
  83. cmd->data_len = qdf_nbuf_len(param->wbuf);
  84. cmd->frame_ctrl = param->frame_ctrl;
  85. cmd->dtim_flag = dtim_flag;
  86. dma_addr = qdf_nbuf_get_frag_paddr(param->wbuf, 0);
  87. cmd->frag_ptr_lo = qdf_get_lower_32_bits(dma_addr);
  88. #if defined(HTT_PADDR64)
  89. cmd->frag_ptr_hi = qdf_get_upper_32_bits(dma_addr) & 0x1F;
  90. #endif
  91. cmd->bcn_antenna = param->bcn_txant;
  92. wmi_mtrace(WMI_PDEV_SEND_BCN_CMDID, cmd->vdev_id, 0);
  93. ret = wmi_unified_cmd_send(wmi_handle, wmi_buf, sizeof(*cmd),
  94. WMI_PDEV_SEND_BCN_CMDID);
  95. if (ret != QDF_STATUS_SUCCESS) {
  96. WMI_LOGE("%s: Failed to send bcn: %d", __func__, ret);
  97. wmi_buf_free(wmi_buf);
  98. }
  99. return ret;
  100. }
  101. static QDF_STATUS
  102. extract_tbttoffset_num_vdevs_tlv(struct wmi_unified *wmi_handle, void *evt_buf,
  103. uint32_t *num_vdevs)
  104. {
  105. WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
  106. wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
  107. uint32_t vdev_map;
  108. param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf;
  109. if (!param_buf) {
  110. WMI_LOGE("%s: Invalid tbtt update ext event buffer", __func__);
  111. return QDF_STATUS_E_INVAL;
  112. }
  113. tbtt_offset_event = param_buf->fixed_param;
  114. vdev_map = tbtt_offset_event->vdev_map;
  115. *num_vdevs = wmi_vdev_map_to_num_vdevs(vdev_map);
  116. return QDF_STATUS_SUCCESS;
  117. }
  118. static QDF_STATUS
  119. send_vdev_set_neighbour_rx_cmd_tlv(struct wmi_unified *wmi_handle,
  120. uint8_t macaddr[QDF_MAC_ADDR_SIZE],
  121. struct set_neighbour_rx_params *param)
  122. {
  123. wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd;
  124. wmi_buf_t buf;
  125. int32_t len = sizeof(*cmd);
  126. buf = wmi_buf_alloc(wmi_handle, len);
  127. if (!buf) {
  128. WMI_LOGE("%s:wmi_buf_alloc failed", __func__);
  129. return QDF_STATUS_E_FAILURE;
  130. }
  131. cmd = (wmi_vdev_filter_nrp_config_cmd_fixed_param *)wmi_buf_data(buf);
  132. WMITLV_SET_HDR(&cmd->tlv_header,
  133. WMITLV_TAG_STRUC_wmi_vdev_filter_nrp_config_cmd_fixed_param,
  134. WMITLV_GET_STRUCT_TLVLEN(
  135. wmi_vdev_filter_nrp_config_cmd_fixed_param));
  136. cmd->vdev_id = param->vdev_id;
  137. cmd->bssid_idx = param->idx;
  138. cmd->action = param->action;
  139. cmd->type = param->type;
  140. WMI_CHAR_ARRAY_TO_MAC_ADDR(macaddr, &cmd->addr);
  141. cmd->flag = 0;
  142. wmi_mtrace(WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID, cmd->vdev_id, 0);
  143. if (wmi_unified_cmd_send(wmi_handle, buf, len,
  144. WMI_VDEV_FILTER_NEIGHBOR_RX_PACKETS_CMDID)) {
  145. WMI_LOGE("Failed to set neighbour rx param");
  146. wmi_buf_free(buf);
  147. return QDF_STATUS_E_FAILURE;
  148. }
  149. return QDF_STATUS_SUCCESS;
  150. }
  151. static QDF_STATUS
  152. extract_vdev_start_resp_tlv(struct wmi_unified *wmi_handle, void *evt_buf,
  153. struct vdev_start_response *vdev_rsp)
  154. {
  155. WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf;
  156. wmi_vdev_start_response_event_fixed_param *ev;
  157. param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *)evt_buf;
  158. if (!param_buf) {
  159. WMI_LOGE("%s: Invalid start response event buffer", __func__);
  160. return QDF_STATUS_E_INVAL;
  161. }
  162. ev = param_buf->fixed_param;
  163. if (!ev) {
  164. WMI_LOGE("%s: Invalid start response event buffer", __func__);
  165. return QDF_STATUS_E_INVAL;
  166. }
  167. qdf_mem_zero(vdev_rsp, sizeof(*vdev_rsp));
  168. vdev_rsp->vdev_id = ev->vdev_id;
  169. vdev_rsp->requestor_id = ev->requestor_id;
  170. switch (ev->resp_type) {
  171. case WMI_VDEV_START_RESP_EVENT:
  172. vdev_rsp->resp_type = WMI_HOST_VDEV_START_RESP_EVENT;
  173. break;
  174. case WMI_VDEV_RESTART_RESP_EVENT:
  175. vdev_rsp->resp_type = WMI_HOST_VDEV_RESTART_RESP_EVENT;
  176. break;
  177. default:
  178. WMI_LOGE("Invalid start response event buffer");
  179. break;
  180. };
  181. vdev_rsp->status = ev->status;
  182. vdev_rsp->chain_mask = ev->chain_mask;
  183. vdev_rsp->smps_mode = ev->smps_mode;
  184. vdev_rsp->mac_id = ev->mac_id;
  185. vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams;
  186. vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams;
  187. vdev_rsp->max_allowed_tx_power = ev->max_allowed_tx_power;
  188. return QDF_STATUS_SUCCESS;
  189. }
  190. static QDF_STATUS
  191. extract_vdev_delete_resp_tlv(struct wmi_unified *wmi_handle, void *evt_buf,
  192. struct vdev_delete_response *delete_rsp)
  193. {
  194. WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf;
  195. wmi_vdev_delete_resp_event_fixed_param *ev;
  196. param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *)evt_buf;
  197. if (!param_buf) {
  198. WMI_LOGE("Invalid vdev delete response event buffer");
  199. return QDF_STATUS_E_INVAL;
  200. }
  201. ev = param_buf->fixed_param;
  202. if (!ev) {
  203. WMI_LOGE("Invalid vdev delete response event");
  204. return QDF_STATUS_E_INVAL;
  205. }
  206. qdf_mem_zero(delete_rsp, sizeof(*delete_rsp));
  207. delete_rsp->vdev_id = ev->vdev_id;
  208. return QDF_STATUS_SUCCESS;
  209. }
  210. static QDF_STATUS extract_vdev_peer_delete_all_response_event_tlv(
  211. wmi_unified_t wmi_hdl,
  212. void *evt_buf,
  213. struct peer_delete_all_response *param)
  214. {
  215. WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID_param_tlvs *param_buf;
  216. wmi_vdev_delete_all_peer_resp_event_fixed_param *ev;
  217. param_buf = (WMI_VDEV_DELETE_ALL_PEER_RESP_EVENTID_param_tlvs *)evt_buf;
  218. ev = (wmi_vdev_delete_all_peer_resp_event_fixed_param *)
  219. param_buf->fixed_param;
  220. if (!ev) {
  221. WMI_LOGE("%s: Invalid peer_delete all response", __func__);
  222. return QDF_STATUS_E_FAILURE;
  223. }
  224. param->vdev_id = ev->vdev_id;
  225. param->status = ev->status;
  226. return QDF_STATUS_SUCCESS;
  227. }
  228. static QDF_STATUS
  229. extract_vdev_stopped_param_tlv(struct wmi_unified *wmi_handle,
  230. void *evt_buf, uint32_t *vdev_id)
  231. {
  232. WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
  233. wmi_vdev_stopped_event_fixed_param *resp_event;
  234. param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *)evt_buf;
  235. if (!param_buf) {
  236. WMI_LOGE("Invalid event buffer");
  237. return QDF_STATUS_E_INVAL;
  238. }
  239. resp_event = param_buf->fixed_param;
  240. *vdev_id = resp_event->vdev_id;
  241. return QDF_STATUS_SUCCESS;
  242. }
  243. static QDF_STATUS extract_ext_tbttoffset_num_vdevs_tlv(
  244. wmi_unified_t wmi_hdl,
  245. void *evt_buf,
  246. uint32_t *num_vdevs)
  247. {
  248. WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
  249. wmi_tbtt_offset_ext_event_fixed_param *tbtt_offset_ext_event;
  250. param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
  251. if (!param_buf) {
  252. WMI_LOGE("%s Invalid tbtt update ext event buffer", __func__);
  253. return QDF_STATUS_E_INVAL;
  254. }
  255. tbtt_offset_ext_event = param_buf->fixed_param;
  256. *num_vdevs = tbtt_offset_ext_event->num_vdevs;
  257. return QDF_STATUS_SUCCESS;
  258. }
  259. static QDF_STATUS extract_tbttoffset_update_params_tlv(
  260. wmi_unified_t wmi_hdl,
  261. void *evt_buf, uint8_t idx,
  262. struct tbttoffset_params *tbtt_param)
  263. {
  264. WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
  265. wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
  266. uint32_t vdev_map;
  267. param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *)evt_buf;
  268. if (!param_buf) {
  269. WMI_LOGE("%s: Invalid tbtt update event buffer", __func__);
  270. return QDF_STATUS_E_INVAL;
  271. }
  272. tbtt_offset_event = param_buf->fixed_param;
  273. vdev_map = tbtt_offset_event->vdev_map;
  274. tbtt_param->vdev_id = wmi_vdev_map_to_vdev_id(vdev_map, idx);
  275. if (tbtt_param->vdev_id == WLAN_INVALID_VDEV_ID)
  276. return QDF_STATUS_E_INVAL;
  277. tbtt_param->tbttoffset =
  278. param_buf->tbttoffset_list[tbtt_param->vdev_id];
  279. if (param_buf->tbtt_qtime_low_us_list)
  280. tbtt_param->vdev_tbtt_qtime_lo =
  281. param_buf->tbtt_qtime_low_us_list[tbtt_param->vdev_id];
  282. if (param_buf->tbtt_qtime_high_us_list)
  283. tbtt_param->vdev_tbtt_qtime_hi =
  284. param_buf->tbtt_qtime_high_us_list[tbtt_param->vdev_id];
  285. return QDF_STATUS_SUCCESS;
  286. }
  287. static QDF_STATUS extract_ext_tbttoffset_update_params_tlv(
  288. wmi_unified_t wmi_hdl,
  289. void *evt_buf, uint8_t idx,
  290. struct tbttoffset_params *tbtt_param)
  291. {
  292. WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *param_buf;
  293. wmi_tbtt_offset_info *tbtt_offset_info;
  294. param_buf = (WMI_TBTTOFFSET_EXT_UPDATE_EVENTID_param_tlvs *)evt_buf;
  295. if (!param_buf) {
  296. WMI_LOGE("%s: Invalid tbtt update event buffer", __func__);
  297. return QDF_STATUS_E_INVAL;
  298. }
  299. tbtt_offset_info = &param_buf->tbtt_offset_info[idx];
  300. tbtt_param->vdev_id = tbtt_offset_info->vdev_id;
  301. tbtt_param->tbttoffset = tbtt_offset_info->tbttoffset;
  302. tbtt_param->vdev_tbtt_qtime_lo = tbtt_offset_info->tbtt_qtime_low_us;
  303. tbtt_param->vdev_tbtt_qtime_hi = tbtt_offset_info->tbtt_qtime_high_us;
  304. return QDF_STATUS_SUCCESS;
  305. }
  306. static QDF_STATUS extract_muedca_params_tlv(wmi_unified_t wmi_hdl,
  307. void *evt_buf,
  308. struct muedca_params *muedca_param_list)
  309. {
  310. WMI_MUEDCA_PARAMS_CONFIG_EVENTID_param_tlvs *param_buf;
  311. wmi_muedca_params_config_event_fixed_param *muedca_param;
  312. int i;
  313. param_buf = (WMI_MUEDCA_PARAMS_CONFIG_EVENTID_param_tlvs *)evt_buf;
  314. if (!param_buf) {
  315. WMI_LOGE("%s: Invalid muedca evt buffer", __func__);
  316. return QDF_STATUS_E_INVAL;
  317. }
  318. muedca_param = param_buf->fixed_param;
  319. muedca_param_list->pdev_id = wmi_hdl->ops->
  320. convert_pdev_id_target_to_host(wmi_hdl,
  321. muedca_param->pdev_id);
  322. for (i = 0; i < WMI_AC_MAX; i++) {
  323. muedca_param_list->muedca_aifsn[i] = muedca_param->aifsn[i] &
  324. WMI_MUEDCA_PARAM_MASK;
  325. muedca_param_list->muedca_ecwmin[i] = muedca_param->ecwmin[i] &
  326. WMI_MUEDCA_PARAM_MASK;
  327. muedca_param_list->muedca_ecwmax[i] = muedca_param->ecwmax[i] &
  328. WMI_MUEDCA_PARAM_MASK;
  329. muedca_param_list->muedca_timer[i] = muedca_param->muedca_expiration_time[i] &
  330. WMI_MUEDCA_PARAM_MASK;
  331. }
  332. return QDF_STATUS_SUCCESS;
  333. }
  334. void wmi_vdev_attach_tlv(struct wmi_unified *wmi_handle)
  335. {
  336. struct wmi_ops *wmi_ops;
  337. if (!wmi_handle) {
  338. WMI_LOGP("%s: null wmi handle", __func__);
  339. return;
  340. }
  341. wmi_ops = wmi_handle->ops;
  342. wmi_ops->extract_vdev_delete_resp = extract_vdev_delete_resp_tlv;
  343. wmi_ops->extract_vdev_stopped_param = extract_vdev_stopped_param_tlv;
  344. wmi_ops->extract_vdev_start_resp = extract_vdev_start_resp_tlv;
  345. wmi_ops->extract_vdev_peer_delete_all_response_event =
  346. extract_vdev_peer_delete_all_response_event_tlv;
  347. wmi_ops->extract_tbttoffset_num_vdevs =
  348. extract_tbttoffset_num_vdevs_tlv;
  349. wmi_ops->extract_tbttoffset_update_params =
  350. extract_tbttoffset_update_params_tlv;
  351. wmi_ops->extract_ext_tbttoffset_update_params =
  352. extract_ext_tbttoffset_update_params_tlv;
  353. wmi_ops->extract_ext_tbttoffset_num_vdevs =
  354. extract_ext_tbttoffset_num_vdevs_tlv;
  355. wmi_ops->extract_muedca_params_handler =
  356. extract_muedca_params_tlv;
  357. wmi_ops->send_vdev_set_neighbour_rx_cmd =
  358. send_vdev_set_neighbour_rx_cmd_tlv;
  359. wmi_ops->send_beacon_send_cmd = send_beacon_send_cmd_tlv;
  360. wmi_ops->send_vdev_config_ratemask_cmd =
  361. send_vdev_config_ratemask_cmd_tlv;
  362. }