123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- #include <osdep.h>
- #include "wmi.h"
- #include "wmi_unified_priv.h"
- #include "wmi_unified_cfr_param.h"
- #include "wmi_unified_cfr_api.h"
- #ifdef WLAN_CFR_ENABLE
- static QDF_STATUS
- extract_cfr_peer_tx_event_param_tlv(wmi_unified_t wmi_handle, void *evt_buf,
- wmi_cfr_peer_tx_event_param *peer_tx_event)
- {
- int idx;
- WMI_PEER_CFR_CAPTURE_EVENTID_param_tlvs *param_buf;
- wmi_peer_cfr_capture_event_fixed_param *peer_tx_event_ev;
- wmi_peer_cfr_capture_event_phase_fixed_param *chain_phase_ev;
- param_buf = (WMI_PEER_CFR_CAPTURE_EVENTID_param_tlvs *)evt_buf;
- if (!param_buf) {
- WMI_LOGE("Invalid cfr capture buffer");
- return QDF_STATUS_E_INVAL;
- }
- peer_tx_event_ev = param_buf->fixed_param;
- if (!peer_tx_event_ev) {
- WMI_LOGE("peer cfr capture buffer is null");
- return QDF_STATUS_E_NULL_VALUE;
- }
- peer_tx_event->capture_method = peer_tx_event_ev->capture_method;
- peer_tx_event->vdev_id = peer_tx_event_ev->vdev_id;
- WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_tx_event_ev->mac_addr,
- &peer_tx_event->peer_mac_addr.bytes[0]);
- peer_tx_event->primary_20mhz_chan =
- peer_tx_event_ev->chan_mhz;
- peer_tx_event->bandwidth = peer_tx_event_ev->bandwidth;
- peer_tx_event->phy_mode = peer_tx_event_ev->phy_mode;
- peer_tx_event->band_center_freq1 = peer_tx_event_ev->band_center_freq1;
- peer_tx_event->band_center_freq2 = peer_tx_event_ev->band_center_freq2;
- peer_tx_event->spatial_streams = peer_tx_event_ev->sts_count;
- peer_tx_event->correlation_info_1 =
- peer_tx_event_ev->correlation_info_1;
- peer_tx_event->correlation_info_2 =
- peer_tx_event_ev->correlation_info_2;
- peer_tx_event->status = peer_tx_event_ev->status;
- peer_tx_event->timestamp_us = peer_tx_event_ev->timestamp_us;
- peer_tx_event->counter = peer_tx_event_ev->counter;
- qdf_mem_copy(peer_tx_event->chain_rssi, peer_tx_event_ev->chain_rssi,
- sizeof(peer_tx_event->chain_rssi));
- chain_phase_ev = param_buf->phase_param;
- if (chain_phase_ev) {
- for (idx = 0; idx < WMI_HOST_MAX_CHAINS; idx++) {
- /* Due to FW's alignment rules, phase information being
- * passed is 32-bit, out of which only 16 bits is valid.
- * Remaining bits are all zeroed. So direct mem copy
- * will not work as it will copy extra zeroes into host
- * structures.
- */
- peer_tx_event->chain_phase[idx] =
- (0xffff & chain_phase_ev->chain_phase[idx]);
- }
- }
- return QDF_STATUS_SUCCESS;
- }
- #ifdef WLAN_ENH_CFR_ENABLE
- static void populate_wmi_cfr_param(uint8_t grp_id, struct cfr_rcc_param *rcc,
- wmi_cfr_filter_group_config *param)
- {
- struct ta_ra_cfr_cfg *tgt_cfg = NULL;
- WMITLV_SET_HDR(¶m->tlv_header,
- WMITLV_TAG_STRUC_wmi_cfr_filter_group_config,
- WMITLV_GET_STRUCT_TLVLEN
- (wmi_cfr_filter_group_config));
- tgt_cfg = &rcc->curr[grp_id];
- param->filter_group_id = grp_id;
- WMI_CFR_GROUP_TA_ADDR_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_ta);
- WMI_CFR_GROUP_TA_ADDR_MASK_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_ta_mask);
- WMI_CFR_GROUP_RA_ADDR_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_ra);
- WMI_CFR_GROUP_RA_ADDR_MASK_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_ra_mask);
- WMI_CFR_GROUP_BW_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_bw_mask);
- WMI_CFR_GROUP_NSS_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_nss_mask);
- WMI_CFR_GROUP_MGMT_SUBTYPE_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_mgmt_subtype);
- WMI_CFR_GROUP_CTRL_SUBTYPE_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_ctrl_subtype);
- WMI_CFR_GROUP_DATA_SUBTYPE_VALID_SET(param->filter_set_valid_mask,
- tgt_cfg->valid_data_subtype);
- WMI_CHAR_ARRAY_TO_MAC_ADDR(tgt_cfg->tx_addr,
- ¶m->ta_addr);
- WMI_CHAR_ARRAY_TO_MAC_ADDR(tgt_cfg->tx_addr_mask,
- ¶m->ta_addr_mask);
- WMI_CHAR_ARRAY_TO_MAC_ADDR(tgt_cfg->rx_addr,
- ¶m->ra_addr);
- WMI_CHAR_ARRAY_TO_MAC_ADDR(tgt_cfg->rx_addr_mask,
- ¶m->ra_addr_mask);
- WMI_CFR_GROUP_BW_SET(param->bw_nss_filter,
- tgt_cfg->bw);
- WMI_CFR_GROUP_NSS_SET(param->bw_nss_filter,
- tgt_cfg->nss);
- param->mgmt_subtype_filter = tgt_cfg->mgmt_subtype_filter;
- param->ctrl_subtype_filter = tgt_cfg->ctrl_subtype_filter;
- param->data_subtype_filter = tgt_cfg->data_subtype_filter;
- }
- static QDF_STATUS send_cfr_rcc_cmd_tlv(wmi_unified_t wmi_handle,
- struct cfr_rcc_param *rcc)
- {
- wmi_cfr_capture_filter_cmd_fixed_param *cmd;
- wmi_cfr_filter_group_config *param;
- uint8_t *buf_ptr, grp_id;
- wmi_buf_t buf;
- uint32_t len;
- QDF_STATUS status = QDF_STATUS_SUCCESS;
- struct wmi_ops *ops = wmi_handle->ops;
- len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
- len += rcc->num_grp_tlvs * sizeof(wmi_cfr_filter_group_config);
- buf = wmi_buf_alloc(wmi_handle, len);
- if (!buf) {
- WMI_LOGE("%s:wmi_buf_alloc failed\n", __func__);
- return QDF_STATUS_E_NOMEM;
- }
- buf_ptr = wmi_buf_data(buf);
- cmd = (wmi_cfr_capture_filter_cmd_fixed_param *)buf_ptr;
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_wmi_cfr_capture_filter_cmd_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN
- (wmi_cfr_capture_filter_cmd_fixed_param));
- cmd->pdev_id = ops->convert_host_pdev_id_to_target(wmi_handle,
- rcc->pdev_id);
- WMI_CFR_CAPTURE_INTERVAL_SET(cmd->capture_interval,
- rcc->capture_interval);
- WMI_CFR_CAPTURE_DURATION_SET(cmd->capture_duration,
- rcc->capture_duration);
- WMI_CFR_CAPTURE_COUNT_SET(cmd->capture_count, rcc->capture_count);
- WMI_CFR_CAPTURE_INTERVAL_MODE_SEL_SET(cmd->capture_count,
- rcc->capture_intval_mode_sel);
- WMI_CFR_FILTER_GROUP_BITMAP_SET(cmd->filter_group_bitmap,
- rcc->filter_group_bitmap);
- WMI_CFR_UL_MU_USER_UPPER_SET(cmd->ul_mu_user_mask_upper,
- rcc->ul_mu_user_mask_upper);
- cmd->ul_mu_user_mask_lower = rcc->ul_mu_user_mask_lower;
- WMI_CFR_FREEZE_DELAY_CNT_EN_SET(cmd->freeze_tlv_delay_cnt,
- rcc->freeze_tlv_delay_cnt_en);
- WMI_CFR_FREEZE_DELAY_CNT_THR_SET(cmd->freeze_tlv_delay_cnt,
- rcc->freeze_tlv_delay_cnt_thr);
- WMI_CFR_DIRECTED_FTM_ACK_EN_SET(cmd->filter_type,
- rcc->m_directed_ftm);
- WMI_CFR_ALL_FTM_ACK_EN_SET(cmd->filter_type,
- rcc->m_all_ftm_ack);
- WMI_CFR_NDPA_NDP_DIRECTED_EN_SET(cmd->filter_type,
- rcc->m_ndpa_ndp_directed);
- WMI_CFR_NDPA_NDP_ALL_EN_SET(cmd->filter_type,
- rcc->m_ndpa_ndp_all);
- WMI_CFR_TA_RA_TYPE_FILTER_EN_SET(cmd->filter_type,
- rcc->m_ta_ra_filter);
- WMI_CFR_FILTER_IN_AS_FP_TA_RA_TYPE_SET(cmd->filter_type,
- rcc->en_ta_ra_filter_in_as_fp);
- WMI_CFR_ALL_PACKET_EN_SET(cmd->filter_type,
- rcc->m_all_packet);
- /* TLV indicating array of structures to follow */
- buf_ptr += sizeof(wmi_cfr_capture_filter_cmd_fixed_param);
- WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
- rcc->num_grp_tlvs * sizeof(wmi_cfr_filter_group_config));
- if (rcc->num_grp_tlvs) {
- buf_ptr += WMI_TLV_HDR_SIZE;
- param = (wmi_cfr_filter_group_config *)buf_ptr;
- for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) {
- if (qdf_test_bit(grp_id,
- (unsigned long *)
- &rcc->modified_in_curr_session)) {
- populate_wmi_cfr_param(grp_id, rcc, param);
- param++;
- }
- }
- }
- status = wmi_unified_cmd_send(wmi_handle, buf, len,
- WMI_CFR_CAPTURE_FILTER_CMDID);
- if (status)
- wmi_buf_free(buf);
- return status;
- }
- #endif
- static QDF_STATUS send_peer_cfr_capture_cmd_tlv(wmi_unified_t wmi_handle,
- struct peer_cfr_params *param)
- {
- wmi_peer_cfr_capture_cmd_fixed_param *cmd;
- wmi_buf_t buf;
- int len = sizeof(*cmd);
- int ret;
- buf = wmi_buf_alloc(wmi_handle, len);
- if (!buf) {
- qdf_print("%s:wmi_buf_alloc failed\n", __func__);
- return QDF_STATUS_E_NOMEM;
- }
- cmd = (wmi_peer_cfr_capture_cmd_fixed_param *)wmi_buf_data(buf);
- WMITLV_SET_HDR(&cmd->tlv_header,
- WMITLV_TAG_STRUC_wmi_peer_cfr_capture_cmd_fixed_param,
- WMITLV_GET_STRUCT_TLVLEN
- (wmi_peer_cfr_capture_cmd_fixed_param));
- WMI_CHAR_ARRAY_TO_MAC_ADDR(param->macaddr, &cmd->mac_addr);
- cmd->request = param->request;
- cmd->vdev_id = param->vdev_id;
- cmd->periodicity = param->periodicity;
- cmd->bandwidth = param->bandwidth;
- cmd->capture_method = param->capture_method;
- ret = wmi_unified_cmd_send(wmi_handle, buf, len,
- WMI_PEER_CFR_CAPTURE_CMDID);
- if (QDF_IS_STATUS_ERROR(ret)) {
- WMI_LOGE("Failed to send WMI_PEER_CFR_CAPTURE_CMDID");
- wmi_buf_free(buf);
- }
- return ret;
- }
- #ifdef WLAN_ENH_CFR_ENABLE
- static inline void wmi_enh_cfr_attach_tlv(wmi_unified_t wmi_handle)
- {
- struct wmi_ops *ops = wmi_handle->ops;
- ops->send_cfr_rcc_cmd = send_cfr_rcc_cmd_tlv;
- }
- #else
- static inline void wmi_enh_cfr_attach_tlv(wmi_unified_t wmi_handle)
- {
- }
- #endif
- void wmi_cfr_attach_tlv(wmi_unified_t wmi_handle)
- {
- struct wmi_ops *ops = wmi_handle->ops;
- ops->send_peer_cfr_capture_cmd = send_peer_cfr_capture_cmd_tlv;
- ops->extract_cfr_peer_tx_event_param =
- extract_cfr_peer_tx_event_param_tlv;
- wmi_enh_cfr_attach_tlv(wmi_handle);
- }
- #endif /* WLAN_CFR_ENABLE */
|