From 9465ea0c01acbfb2f58c56dbfe47eb2994574f51 Mon Sep 17 00:00:00 2001 From: Dundi Raviteja Date: Mon, 3 Feb 2020 18:05:21 +0530 Subject: [PATCH] qcacld-3.0: Add WMI EVENT handler for offloaded mgmt data Register event handler for WMI_VDEV_MGMT_OFFLOAD_DATA_EVENTID to handle offloaded management data. Change-Id: I340d79b08f8453425092f4582059f184e0dfb625 CRs-Fixed: 2619319 --- .../pkt_capture/inc/target_if_pkt_capture.h | 19 ++- .../pkt_capture/src/target_if_pkt_capture.c | 124 +++++++++++++++++- 2 files changed, 139 insertions(+), 4 deletions(-) diff --git a/components/target_if/pkt_capture/inc/target_if_pkt_capture.h b/components/target_if/pkt_capture/inc/target_if_pkt_capture.h index 8e4aedf03f99..f8269e2e0ec1 100644 --- a/components/target_if/pkt_capture/inc/target_if_pkt_capture.h +++ b/components/target_if/pkt_capture/inc/target_if_pkt_capture.h @@ -25,8 +25,12 @@ #ifndef _TARGET_IF_PKT_CAPTURE_H_ #define _TARGET_IF_PKT_CAPTURE_H_ -#include -#include "wlan_pkt_capture_public_structs.h" +#include +#include +#include +#include +#include +#include /** * target_if_set_packet_capture_mode() - set packet capture mode @@ -39,4 +43,15 @@ QDF_STATUS target_if_set_packet_capture_mode(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, enum pkt_capture_mode mode); + +/** + * target_if_register_mgmt_data_offload_event() - Register offload event handler + * @psoc: wlan psoc object + * + * Register mgmt data offload event handler + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_register_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc); #endif /* _TARGET_IF_PKT_CAPTURE_H_ */ diff --git a/components/target_if/pkt_capture/src/target_if_pkt_capture.c b/components/target_if/pkt_capture/src/target_if_pkt_capture.c index d2d4bffea8d2..9ae1a854dade 100644 --- a/components/target_if/pkt_capture/src/target_if_pkt_capture.c +++ b/components/target_if/pkt_capture/src/target_if_pkt_capture.c @@ -22,8 +22,6 @@ * in target_if internally. */ -#include -#include #include #include #include @@ -59,3 +57,125 @@ QDF_STATUS target_if_set_packet_capture_mode(struct wlan_objmgr_psoc *psoc, } return status; } + +/** + * target_if_mgmt_offload_data_event_handler() - offload event handler + * @handle: scn handle + * @data: mgmt data + * @data_len: data length + * + * Process management offload frame. + * + * Return: 0 for success or error code + */ +static int +target_if_mgmt_offload_data_event_handler(void *handle, uint8_t *data, + uint32_t data_len) +{ + static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1; + struct mgmt_offload_event_params params; + struct wmi_unified *wmi_handle; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + QDF_STATUS status; + qdf_nbuf_t wbuf; + + psoc = target_if_get_psoc_from_scn_hdl(handle); + if (!psoc) { + pkt_capture_err("psoc is NULL"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid WMI handle"); + return -EINVAL; + } + + pdev = target_if_get_pdev_from_scn_hdl(handle); + if (!pdev) { + pkt_capture_err("pdev is NULL"); + return -EINVAL; + } + + if (!(ucfg_pkt_capture_get_pktcap_mode(psoc) & + PKT_CAPTURE_MODE_MGMT_ONLY)) + return -EINVAL; + + status = wmi_unified_extract_vdev_mgmt_offload_event(wmi_handle, data, + ¶ms); + if (QDF_IS_STATUS_ERROR(status)) { + pkt_capture_err("Extract mgmt offload event failed"); + return -EINVAL; + } + + if (!params.buf) { + pkt_capture_err("Mgmt offload buf is NULL"); + return -EINVAL; + } + + if (params.buf_len < sizeof(struct ieee80211_hdr_3addr) || + params.buf_len > data_len) { + limit_prints_invalid_len++; + if (limit_prints_invalid_len == RATE_LIMIT) { + pkt_capture_debug( + "Invalid mgmt packet, data_len %u, params.buf_len %u", + data_len, params.buf_len); + limit_prints_invalid_len = 0; + } + return -EINVAL; + } + + wbuf = qdf_nbuf_alloc(NULL, + roundup(params.buf_len + RESERVE_BYTES, 4), + RESERVE_BYTES, 4, false); + if (!wbuf) { + pkt_capture_err("Failed to allocate wbuf for mgmt pkt len(%u)", + params.buf_len); + return -ENOMEM; + } + + qdf_nbuf_put_tail(wbuf, params.buf_len); + qdf_nbuf_set_protocol(wbuf, ETH_P_CONTROL); + qdf_mem_copy(qdf_nbuf_data(wbuf), params.buf, params.buf_len); + + status = params.tx_status; + if (QDF_STATUS_SUCCESS != + ucfg_pkt_capture_process_mgmt_tx_data(pdev, ¶ms, + wbuf, status)) + qdf_nbuf_free(wbuf); + + return 0; +} + +QDF_STATUS +target_if_register_mgmt_data_offload_event(struct wlan_objmgr_psoc *psoc) +{ + wmi_unified_t wmi_handle; + + PKT_CAPTURE_ENTER(); + + if (!psoc) { + pkt_capture_err("psoc got NULL"); + return QDF_STATUS_E_FAILURE; + } + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + + if (ucfg_pkt_capture_get_mode(psoc) && + wmi_service_enabled(wmi_handle, + wmi_service_packet_capture_support)) { + uint8_t status; + + status = wmi_unified_register_event_handler( + wmi_handle, + wmi_mgmt_offload_data_event_id, + target_if_mgmt_offload_data_event_handler, + WMI_RX_WORK_CTX); + if (status) { + pkt_capture_err("Failed to register MGMT offload handler"); + return QDF_STATUS_E_FAILURE; + } + } + PKT_CAPTURE_ENTER(); + return QDF_STATUS_SUCCESS; +}