wmi_unified_cfr_tlv.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * Copyright (c) 2019-2020, 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_host_pdev_id_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_CAPTURE_COUNT_SET(cmd->capture_count, rcc->capture_count);
  150. WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_SET(cmd->capture_count,
  151. rcc->capture_intval_mode_sel);
  152. WMI_CFR_FILTER_GROUP_BITMAP_SET(cmd->filter_group_bitmap,
  153. rcc->filter_group_bitmap);
  154. WMI_CFR_UL_MU_USER_UPPER_SET(cmd->ul_mu_user_mask_upper,
  155. rcc->ul_mu_user_mask_upper);
  156. cmd->ul_mu_user_mask_lower = rcc->ul_mu_user_mask_lower;
  157. WMI_CFR_FREEZE_DELAY_CNT_EN_SET(cmd->freeze_tlv_delay_cnt,
  158. rcc->freeze_tlv_delay_cnt_en);
  159. WMI_CFR_FREEZE_DELAY_CNT_THR_SET(cmd->freeze_tlv_delay_cnt,
  160. rcc->freeze_tlv_delay_cnt_thr);
  161. WMI_CFR_DIRECTED_FTM_ACK_EN_SET(cmd->filter_type,
  162. rcc->m_directed_ftm);
  163. WMI_CFR_ALL_FTM_ACK_EN_SET(cmd->filter_type,
  164. rcc->m_all_ftm_ack);
  165. WMI_CFR_NDPA_NDP_DIRECTED_EN_SET(cmd->filter_type,
  166. rcc->m_ndpa_ndp_directed);
  167. WMI_CFR_NDPA_NDP_ALL_EN_SET(cmd->filter_type,
  168. rcc->m_ndpa_ndp_all);
  169. WMI_CFR_TA_RA_TYPE_FILTER_EN_SET(cmd->filter_type,
  170. rcc->m_ta_ra_filter);
  171. WMI_CFR_FILTER_IN_AS_FP_TA_RA_TYPE_SET(cmd->filter_type,
  172. rcc->en_ta_ra_filter_in_as_fp);
  173. WMI_CFR_ALL_PACKET_EN_SET(cmd->filter_type,
  174. rcc->m_all_packet);
  175. /* TLV indicating array of structures to follow */
  176. buf_ptr += sizeof(wmi_cfr_capture_filter_cmd_fixed_param);
  177. WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
  178. rcc->num_grp_tlvs * sizeof(wmi_cfr_filter_group_config));
  179. if (rcc->num_grp_tlvs) {
  180. buf_ptr += WMI_TLV_HDR_SIZE;
  181. param = (wmi_cfr_filter_group_config *)buf_ptr;
  182. for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) {
  183. if (qdf_test_bit(grp_id,
  184. (unsigned long *)
  185. &rcc->modified_in_curr_session)) {
  186. populate_wmi_cfr_param(grp_id, rcc, param);
  187. param++;
  188. }
  189. }
  190. }
  191. status = wmi_unified_cmd_send(wmi_handle, buf, len,
  192. WMI_CFR_CAPTURE_FILTER_CMDID);
  193. if (status)
  194. wmi_buf_free(buf);
  195. return status;
  196. }
  197. #endif
  198. static QDF_STATUS send_peer_cfr_capture_cmd_tlv(wmi_unified_t wmi_handle,
  199. struct peer_cfr_params *param)
  200. {
  201. wmi_peer_cfr_capture_cmd_fixed_param *cmd;
  202. wmi_buf_t buf;
  203. int len = sizeof(*cmd);
  204. int ret;
  205. buf = wmi_buf_alloc(wmi_handle, len);
  206. if (!buf) {
  207. qdf_print("%s:wmi_buf_alloc failed\n", __func__);
  208. return QDF_STATUS_E_NOMEM;
  209. }
  210. cmd = (wmi_peer_cfr_capture_cmd_fixed_param *)wmi_buf_data(buf);
  211. WMITLV_SET_HDR(&cmd->tlv_header,
  212. WMITLV_TAG_STRUC_wmi_peer_cfr_capture_cmd_fixed_param,
  213. WMITLV_GET_STRUCT_TLVLEN
  214. (wmi_peer_cfr_capture_cmd_fixed_param));
  215. WMI_CHAR_ARRAY_TO_MAC_ADDR(param->macaddr, &cmd->mac_addr);
  216. cmd->request = param->request;
  217. cmd->vdev_id = param->vdev_id;
  218. cmd->periodicity = param->periodicity;
  219. cmd->bandwidth = param->bandwidth;
  220. cmd->capture_method = param->capture_method;
  221. ret = wmi_unified_cmd_send(wmi_handle, buf, len,
  222. WMI_PEER_CFR_CAPTURE_CMDID);
  223. if (QDF_IS_STATUS_ERROR(ret)) {
  224. WMI_LOGE("Failed to send WMI_PEER_CFR_CAPTURE_CMDID");
  225. wmi_buf_free(buf);
  226. }
  227. return ret;
  228. }
  229. #ifdef WLAN_ENH_CFR_ENABLE
  230. static inline void wmi_enh_cfr_attach_tlv(wmi_unified_t wmi_handle)
  231. {
  232. struct wmi_ops *ops = wmi_handle->ops;
  233. ops->send_cfr_rcc_cmd = send_cfr_rcc_cmd_tlv;
  234. }
  235. #else
  236. static inline void wmi_enh_cfr_attach_tlv(wmi_unified_t wmi_handle)
  237. {
  238. }
  239. #endif
  240. void wmi_cfr_attach_tlv(wmi_unified_t wmi_handle)
  241. {
  242. struct wmi_ops *ops = wmi_handle->ops;
  243. ops->send_peer_cfr_capture_cmd = send_peer_cfr_capture_cmd_tlv;
  244. ops->extract_cfr_peer_tx_event_param =
  245. extract_cfr_peer_tx_event_param_tlv;
  246. wmi_enh_cfr_attach_tlv(wmi_handle);
  247. }
  248. #endif /* WLAN_CFR_ENABLE */