wmi_unified_cfr_tlv.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * Copyright (c) 2019, The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <osdep.h>
  17. #include "wmi.h"
  18. #include "wmi_unified_priv.h"
  19. #include "wmi_unified_cfr_param.h"
  20. #include "wmi_unified_cfr_api.h"
  21. #ifdef WLAN_CFR_ENABLE
  22. static QDF_STATUS
  23. extract_cfr_peer_tx_event_param_tlv(wmi_unified_t wmi_handle, void *evt_buf,
  24. wmi_cfr_peer_tx_event_param *peer_tx_event)
  25. {
  26. int idx;
  27. WMI_PEER_CFR_CAPTURE_EVENTID_param_tlvs *param_buf;
  28. wmi_peer_cfr_capture_event_fixed_param *peer_tx_event_ev;
  29. wmi_peer_cfr_capture_event_phase_fixed_param *chain_phase_ev;
  30. param_buf = (WMI_PEER_CFR_CAPTURE_EVENTID_param_tlvs *)evt_buf;
  31. if (!param_buf) {
  32. WMI_LOGE("Invalid cfr capture buffer");
  33. return QDF_STATUS_E_INVAL;
  34. }
  35. peer_tx_event_ev = param_buf->fixed_param;
  36. if (!peer_tx_event_ev) {
  37. WMI_LOGE("peer cfr capture buffer is null");
  38. return QDF_STATUS_E_NULL_VALUE;
  39. }
  40. peer_tx_event->capture_method = peer_tx_event_ev->capture_method;
  41. peer_tx_event->vdev_id = peer_tx_event_ev->vdev_id;
  42. WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_tx_event_ev->mac_addr,
  43. &peer_tx_event->peer_mac_addr.bytes[0]);
  44. peer_tx_event->primary_20mhz_chan =
  45. peer_tx_event_ev->chan_mhz;
  46. peer_tx_event->bandwidth = peer_tx_event_ev->bandwidth;
  47. peer_tx_event->phy_mode = peer_tx_event_ev->phy_mode;
  48. peer_tx_event->band_center_freq1 = peer_tx_event_ev->band_center_freq1;
  49. peer_tx_event->band_center_freq2 = peer_tx_event_ev->band_center_freq2;
  50. peer_tx_event->spatial_streams = peer_tx_event_ev->sts_count;
  51. peer_tx_event->correlation_info_1 =
  52. peer_tx_event_ev->correlation_info_1;
  53. peer_tx_event->correlation_info_2 =
  54. peer_tx_event_ev->correlation_info_2;
  55. peer_tx_event->status = peer_tx_event_ev->status;
  56. peer_tx_event->timestamp_us = peer_tx_event_ev->timestamp_us;
  57. peer_tx_event->counter = peer_tx_event_ev->counter;
  58. qdf_mem_copy(peer_tx_event->chain_rssi, peer_tx_event_ev->chain_rssi,
  59. sizeof(peer_tx_event->chain_rssi));
  60. chain_phase_ev = param_buf->phase_param;
  61. if (chain_phase_ev) {
  62. for (idx = 0; idx < WMI_HOST_MAX_CHAINS; idx++) {
  63. /* Due to FW's alignment rules, phase information being
  64. * passed is 32-bit, out of which only 16 bits is valid.
  65. * Remaining bits are all zeroed. So direct mem copy
  66. * will not work as it will copy extra zeroes into host
  67. * structures.
  68. */
  69. peer_tx_event->chain_phase[idx] =
  70. (0xffff & chain_phase_ev->chain_phase[idx]);
  71. }
  72. }
  73. return QDF_STATUS_SUCCESS;
  74. }
  75. #ifdef WLAN_ENH_CFR_ENABLE
  76. static void populate_wmi_cfr_param(uint8_t grp_id, struct cfr_rcc_param *rcc,
  77. wmi_cfr_filter_group_config *param)
  78. {
  79. struct ta_ra_cfr_cfg *tgt_cfg = NULL;
  80. WMITLV_SET_HDR(&param->tlv_header,
  81. WMITLV_TAG_STRUC_wmi_cfr_filter_group_config,
  82. WMITLV_GET_STRUCT_TLVLEN
  83. (wmi_cfr_filter_group_config));
  84. tgt_cfg = &rcc->curr[grp_id];
  85. param->filter_group_id = grp_id;
  86. WMI_CFR_GROUP_TA_ADDR_VALID_SET(param->filter_set_valid_mask,
  87. tgt_cfg->valid_ta);
  88. WMI_CFR_GROUP_TA_ADDR_MASK_VALID_SET(param->filter_set_valid_mask,
  89. tgt_cfg->valid_ta_mask);
  90. WMI_CFR_GROUP_RA_ADDR_VALID_SET(param->filter_set_valid_mask,
  91. tgt_cfg->valid_ra);
  92. WMI_CFR_GROUP_RA_ADDR_MASK_VALID_SET(param->filter_set_valid_mask,
  93. tgt_cfg->valid_ra_mask);
  94. WMI_CFR_GROUP_BW_VALID_SET(param->filter_set_valid_mask,
  95. tgt_cfg->valid_bw_mask);
  96. WMI_CFR_GROUP_NSS_VALID_SET(param->filter_set_valid_mask,
  97. tgt_cfg->valid_nss_mask);
  98. WMI_CFR_GROUP_MGMT_SUBTYPE_VALID_SET(param->filter_set_valid_mask,
  99. tgt_cfg->valid_mgmt_subtype);
  100. WMI_CFR_GROUP_CTRL_SUBTYPE_VALID_SET(param->filter_set_valid_mask,
  101. tgt_cfg->valid_ctrl_subtype);
  102. WMI_CFR_GROUP_DATA_SUBTYPE_VALID_SET(param->filter_set_valid_mask,
  103. tgt_cfg->valid_data_subtype);
  104. WMI_CHAR_ARRAY_TO_MAC_ADDR(tgt_cfg->tx_addr,
  105. &param->ta_addr);
  106. WMI_CHAR_ARRAY_TO_MAC_ADDR(tgt_cfg->tx_addr_mask,
  107. &param->ta_addr_mask);
  108. WMI_CHAR_ARRAY_TO_MAC_ADDR(tgt_cfg->rx_addr,
  109. &param->ra_addr);
  110. WMI_CHAR_ARRAY_TO_MAC_ADDR(tgt_cfg->rx_addr_mask,
  111. &param->ra_addr_mask);
  112. WMI_CFR_GROUP_BW_SET(param->bw_nss_filter,
  113. tgt_cfg->bw);
  114. WMI_CFR_GROUP_NSS_SET(param->bw_nss_filter,
  115. tgt_cfg->nss);
  116. param->mgmt_subtype_filter = tgt_cfg->mgmt_subtype_filter;
  117. param->ctrl_subtype_filter = tgt_cfg->ctrl_subtype_filter;
  118. param->data_subtype_filter = tgt_cfg->data_subtype_filter;
  119. }
  120. static QDF_STATUS send_cfr_rcc_cmd_tlv(wmi_unified_t wmi_handle,
  121. struct cfr_rcc_param *rcc)
  122. {
  123. wmi_cfr_capture_filter_cmd_fixed_param *cmd;
  124. wmi_cfr_filter_group_config *param;
  125. uint8_t *buf_ptr, grp_id;
  126. wmi_buf_t buf;
  127. uint32_t len;
  128. QDF_STATUS status = QDF_STATUS_SUCCESS;
  129. struct wmi_ops *ops = wmi_handle->ops;
  130. len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
  131. len += rcc->num_grp_tlvs * sizeof(wmi_cfr_filter_group_config);
  132. buf = wmi_buf_alloc(wmi_handle, len);
  133. if (!buf) {
  134. WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
  135. return QDF_STATUS_E_NOMEM;
  136. }
  137. buf_ptr = wmi_buf_data(buf);
  138. cmd = (wmi_cfr_capture_filter_cmd_fixed_param *)buf_ptr;
  139. WMITLV_SET_HDR(&cmd->tlv_header,
  140. WMITLV_TAG_STRUC_wmi_cfr_capture_filter_cmd_fixed_param,
  141. WMITLV_GET_STRUCT_TLVLEN
  142. (wmi_cfr_capture_filter_cmd_fixed_param));
  143. cmd->pdev_id = ops->convert_pdev_id_host_to_target(wmi_handle,
  144. rcc->pdev_id);
  145. WMI_CFR_CAPTURE_INTERVAL_SET(cmd->capture_interval,
  146. rcc->capture_interval);
  147. WMI_CFR_CAPTURE_DURATION_SET(cmd->capture_duration,
  148. rcc->capture_duration);
  149. WMI_CFR_FILTER_GROUP_BITMAP_SET(cmd->filter_group_bitmap,
  150. rcc->filter_group_bitmap);
  151. WMI_CFR_UL_MU_USER_UPPER_SET(cmd->ul_mu_user_mask_upper,
  152. rcc->ul_mu_user_mask_upper);
  153. cmd->ul_mu_user_mask_lower = rcc->ul_mu_user_mask_lower;
  154. WMI_CFR_FREEZE_DELAY_CNT_EN_SET(cmd->freeze_tlv_delay_cnt,
  155. rcc->freeze_tlv_delay_cnt_en);
  156. WMI_CFR_FREEZE_DELAY_CNT_THR_SET(cmd->freeze_tlv_delay_cnt,
  157. rcc->freeze_tlv_delay_cnt_thr);
  158. WMI_CFR_DIRECTED_FTM_ACK_EN_SET(cmd->filter_type,
  159. rcc->m_directed_ftm);
  160. WMI_CFR_ALL_FTM_ACK_EN_SET(cmd->filter_type,
  161. rcc->m_all_ftm_ack);
  162. WMI_CFR_NDPA_NDP_DIRECTED_EN_SET(cmd->filter_type,
  163. rcc->m_ndpa_ndp_directed);
  164. WMI_CFR_NDPA_NDP_ALL_EN_SET(cmd->filter_type,
  165. rcc->m_ndpa_ndp_all);
  166. WMI_CFR_TA_RA_TYPE_FILTER_EN_SET(cmd->filter_type,
  167. rcc->m_ta_ra_filter);
  168. WMI_CFR_ALL_PACKET_EN_SET(cmd->filter_type,
  169. rcc->m_all_packet);
  170. /* TLV indicating array of structures to follow */
  171. buf_ptr += sizeof(wmi_cfr_capture_filter_cmd_fixed_param);
  172. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  173. rcc->num_grp_tlvs * sizeof(wmi_cfr_filter_group_config));
  174. if (rcc->num_grp_tlvs) {
  175. buf_ptr += WMI_TLV_HDR_SIZE;
  176. param = (wmi_cfr_filter_group_config *)buf_ptr;
  177. for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) {
  178. if (qdf_test_bit(grp_id,
  179. (unsigned long *)
  180. &rcc->modified_in_curr_session)) {
  181. populate_wmi_cfr_param(grp_id, rcc, param);
  182. param++;
  183. }
  184. }
  185. }
  186. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  187. WMI_CFR_CAPTURE_FILTER_CMDID);
  188. if (status)
  189. wmi_buf_free(buf);
  190. return status;
  191. }
  192. #endif
  193. static QDF_STATUS send_peer_cfr_capture_cmd_tlv(wmi_unified_t wmi_handle,
  194. struct peer_cfr_params *param)
  195. {
  196. wmi_peer_cfr_capture_cmd_fixed_param *cmd;
  197. wmi_buf_t buf;
  198. int len = sizeof(*cmd);
  199. int ret;
  200. buf = wmi_buf_alloc(wmi_handle, len);
  201. if (!buf) {
  202. qdf_print("%s:wmi_buf_alloc failed\n", __func__);
  203. return QDF_STATUS_E_NOMEM;
  204. }
  205. cmd = (wmi_peer_cfr_capture_cmd_fixed_param *)wmi_buf_data(buf);
  206. WMITLV_SET_HDR(&cmd->tlv_header,
  207. WMITLV_TAG_STRUC_wmi_peer_cfr_capture_cmd_fixed_param,
  208. WMITLV_GET_STRUCT_TLVLEN
  209. (wmi_peer_cfr_capture_cmd_fixed_param));
  210. WMI_CHAR_ARRAY_TO_MAC_ADDR(param->macaddr, &cmd->mac_addr);
  211. cmd->request = param->request;
  212. cmd->vdev_id = param->vdev_id;
  213. cmd->periodicity = param->periodicity;
  214. cmd->bandwidth = param->bandwidth;
  215. cmd->capture_method = param->capture_method;
  216. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  217. WMI_PEER_CFR_CAPTURE_CMDID);
  218. if (QDF_IS_STATUS_ERROR(ret)) {
  219. WMI_LOGE("Failed to send WMI_PEER_CFR_CAPTURE_CMDID");
  220. wmi_buf_free(buf);
  221. }
  222. return ret;
  223. }
  224. #ifdef WLAN_ENH_CFR_ENABLE
  225. static inline void wmi_enh_cfr_attach_tlv(wmi_unified_t wmi_handle)
  226. {
  227. struct wmi_ops *ops = wmi_handle->ops;
  228. ops->send_cfr_rcc_cmd = send_cfr_rcc_cmd_tlv;
  229. }
  230. #else
  231. static inline void wmi_enh_cfr_attach_tlv(wmi_unified_t wmi_handle)
  232. {
  233. }
  234. #endif
  235. void wmi_cfr_attach_tlv(wmi_unified_t wmi_handle)
  236. {
  237. struct wmi_ops *ops = wmi_handle->ops;
  238. ops->send_peer_cfr_capture_cmd = send_peer_cfr_capture_cmd_tlv;
  239. ops->extract_cfr_peer_tx_event_param =
  240. extract_cfr_peer_tx_event_param_tlv;
  241. wmi_enh_cfr_attach_tlv(wmi_handle);
  242. }
  243. #endif /* WLAN_CFR_ENABLE */