From 4a89130e933b2ebcc3025f78ad723bcb85a79cd5 Mon Sep 17 00:00:00 2001 From: Dundi Raviteja Date: Wed, 29 Jan 2020 11:42:54 +0530 Subject: [PATCH] qcacld-3.0: Process Mgmt Tx and Rx frames for pktcapture mode Process management Tx and Rx frames for packet capture mode and post frames to the mon thread. Change-Id: I14c0a1cf8a8aa4d4a4e16ad6200715b875611c81 CRs-Fixed: 2619317 --- Kbuild | 2 + .../core/inc/wlan_pkt_capture_main.h | 8 + .../core/inc/wlan_pkt_capture_mgmt_txrx.h | 80 ++++ .../core/src/wlan_pkt_capture_main.c | 29 ++ .../core/src/wlan_pkt_capture_mgmt_txrx.c | 360 ++++++++++++++++++ .../inc/wlan_pkt_capture_public_structs.h | 23 ++ .../inc/wlan_pkt_capture_ucfg_api.h | 49 +++ .../src/wlan_pkt_capture_ucfg_api.c | 38 ++ core/wma/src/wma_mgmt.c | 56 ++- 9 files changed, 640 insertions(+), 5 deletions(-) create mode 100644 components/pkt_capture/core/inc/wlan_pkt_capture_mgmt_txrx.h create mode 100644 components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c diff --git a/Kbuild b/Kbuild index de49b93baa6dd..73319482ef0ec 100644 --- a/Kbuild +++ b/Kbuild @@ -1052,6 +1052,8 @@ ifeq ($(CONFIG_WLAN_FEATURE_PKT_CAPTURE), y) PKT_CAPTURE_OBJS := $(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_main.o \ $(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_mon_thread.o \ $(PKT_CAPTURE_DIR)/dispatcher/src/wlan_pkt_capture_ucfg_api.o \ + $(PKT_CAPTURE_DIR)/core/src/wlan_pkt_capture_mgmt_txrx.o \ + $(PKT_CAPTURE_DIR)/dispatcher/src/wlan_pkt_capture_ucfg_api.o \ $(PKT_CAPTURE_TARGET_IF_DIR)/src/target_if_pkt_capture.o endif diff --git a/components/pkt_capture/core/inc/wlan_pkt_capture_main.h b/components/pkt_capture/core/inc/wlan_pkt_capture_main.h index a0ce92b2717bc..f5f316275f9a9 100644 --- a/components/pkt_capture/core/inc/wlan_pkt_capture_main.h +++ b/components/pkt_capture/core/inc/wlan_pkt_capture_main.h @@ -146,4 +146,12 @@ void pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc *psoc, */ enum pkt_capture_mode pkt_capture_get_pktcap_mode(struct wlan_objmgr_psoc *psoc); + +/** + * pkt_capture_drop_nbuf_list() - drop an nbuf list + * @buf_list: buffer list to be dropepd + * + * Return: number of buffers dropped + */ +uint32_t pkt_capture_drop_nbuf_list(qdf_nbuf_t buf_list); #endif /* end of _WLAN_PKT_CAPTURE_MAIN_H_ */ diff --git a/components/pkt_capture/core/inc/wlan_pkt_capture_mgmt_txrx.h b/components/pkt_capture/core/inc/wlan_pkt_capture_mgmt_txrx.h new file mode 100644 index 0000000000000..60692788a54ad --- /dev/null +++ b/components/pkt_capture/core/inc/wlan_pkt_capture_mgmt_txrx.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 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. + */ + +/** + * DOC: Declare mgmt txrx APIs which shall be used internally only + * in pkt_capture component. + * Note: These APIs should be never accessed out of pkt_capture component. + */ + +#ifndef _WLAN_PKT_CAPTURE_MGMT_TXRX_H_ +#define _WLAN_PKT_CAPTURE_MGMT_TXRX_H_ + +#include "wlan_pkt_capture_public_structs.h" + +#define PKTCAPTURE_PKT_FORMAT_8023 (0) +#define PKTCAPTURE_PKT_FORMAT_80211 (1) +#define WLAN_INVALID_TID (31) +#define RESERVE_BYTES (100) +#define RATE_LIMIT (16) +#define INVALID_RSSI_FOR_TX (-128) + +/** + * pkt_capture_process_mgmt_tx_data() - process management tx packets + * @pdev: pointer to pdev object + * @params: management offload event params + * @nbuf: netbuf + * @status: status + * + * Return: QDF_STATUS + */ +QDF_STATUS +pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev, + struct mgmt_offload_event_params *params, + qdf_nbuf_t nbuf, + uint8_t status); + +/** + * pkt_capture_mgmt_tx_completion() - process mgmt tx completion + * for pkt capture mode + * @pdev: pointer to pdev object + * @desc_id: desc_id + * @status: status + * @params: management offload event params + * + * Return: none + */ +void +pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, + uint32_t desc_id, + uint32_t status, + struct mgmt_offload_event_params *params); + +/** + * pkt_capture_mgmt_rx_ops() - Register packet capture mgmt rx ops + * @psoc: psoc context + * @is_register: register if true, unregister if false + * + * This funciton registers or deregisters rx callback + * to mgmt txrx component. + * + * Return: QDF_STATUS + */ +QDF_STATUS pkt_capture_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, + bool is_register); +#endif diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_main.c b/components/pkt_capture/core/src/wlan_pkt_capture_main.c index ad257bd596a7c..1c5a80a7c1b24 100644 --- a/components/pkt_capture/core/src/wlan_pkt_capture_main.c +++ b/components/pkt_capture/core/src/wlan_pkt_capture_main.c @@ -24,6 +24,7 @@ #include "wlan_pkt_capture_main.h" #include "cfg_ucfg_api.h" #include "wlan_pkt_capture_mon_thread.h" +#include "wlan_pkt_capture_mgmt_txrx.h" enum pkt_capture_mode pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc) { @@ -49,6 +50,7 @@ pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev, void *context) { struct pkt_capture_vdev_priv *vdev_priv; + QDF_STATUS status; if (!vdev) { pkt_capture_err("vdev is NULL"); @@ -64,12 +66,19 @@ pkt_capture_register_callbacks(struct wlan_objmgr_vdev *vdev, vdev_priv->cb_ctx->mon_cb = mon_cb; vdev_priv->cb_ctx->mon_ctx = context; + status = pkt_capture_mgmt_rx_ops(wlan_vdev_get_psoc(vdev), true); + if (QDF_IS_STATUS_ERROR(status)) { + pkt_capture_err("Failed to register pkt capture mgmt rx ops"); + return status; + } + return QDF_STATUS_SUCCESS; } QDF_STATUS pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev *vdev) { struct pkt_capture_vdev_priv *vdev_priv; + QDF_STATUS status; if (!vdev) { pkt_capture_err("vdev is NULL"); @@ -82,6 +91,10 @@ QDF_STATUS pkt_capture_deregister_callbacks(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_E_INVAL; } + status = pkt_capture_mgmt_rx_ops(wlan_vdev_get_psoc(vdev), false); + if (QDF_IS_STATUS_ERROR(status)) + pkt_capture_err("Failed to unregister pkt capture mgmt rx ops"); + vdev_priv->cb_ctx->mon_cb = NULL; vdev_priv->cb_ctx->mon_ctx = NULL; @@ -218,6 +231,22 @@ pkt_capture_mon_context_destroy(struct pkt_capture_vdev_priv *vdev_priv) qdf_mem_free(vdev_priv->mon_ctx); } +uint32_t pkt_capture_drop_nbuf_list(qdf_nbuf_t buf_list) +{ + qdf_nbuf_t buf, next_buf; + uint32_t num_dropped = 0; + + buf = buf_list; + while (buf) { + QDF_NBUF_CB_RX_PEER_CACHED_FRM(buf) = 1; + next_buf = qdf_nbuf_queue_next(buf); + qdf_nbuf_free(buf); + buf = next_buf; + num_dropped++; + } + return num_dropped; +} + /** * pkt_capture_cfg_init() - Initialize packet capture cfg ini params * @psoc_priv: psoc private object diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c b/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c new file mode 100644 index 0000000000000..e75bfb143eacb --- /dev/null +++ b/components/pkt_capture/core/src/wlan_pkt_capture_mgmt_txrx.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 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. + */ + +/** + * DOC: Implement mgmt txrx APIs which shall be used internally only + * in pkt_capture component. + * Note: These APIs should be never accessed out of pkt_capture component. + */ + +#include "wlan_pkt_capture_main.h" +#include "wlan_pkt_capture_priv.h" +#include "wlan_pkt_capture_mgmt_txrx.h" +#include "wlan_mlme_main.h" +#include "wlan_lmac_if_api.h" +#include "wlan_mgmt_txrx_utils_api.h" +#include "wlan_utility.h" +#include "cds_ieee80211_common.h" + +/** + * pkt_capture_mgmtpkt_cb() - callback to process management packets + * for pkt capture mode + * @context: vdev handler + * @nbuf_list: netbuf list + * @vdev_id: vdev id for which packet is captured + * @tid: tid number + * @status: Tx status + * @pkt_format: Frame format + * + * Return: none + */ +static void +pkt_capture_mgmtpkt_cb(void *context, void *nbuf_list, + uint8_t vdev_id, uint8_t tid, uint8_t status, + bool pkt_format) +{ + struct pkt_capture_vdev_priv *vdev_priv; + struct wlan_objmgr_psoc *psoc = context; + struct pkt_capture_cb_context *cb_ctx; + struct wlan_objmgr_vdev *vdev; + qdf_nbuf_t msdu, next_buf; + uint32_t drop_count; + + vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, + QDF_STA_MODE, + WLAN_PKT_CAPTURE_ID); + if (!vdev) { + pkt_capture_err("vdev is NULL"); + goto free_buf; + } + + vdev_priv = pkt_capture_vdev_get_priv(vdev); + if (!vdev_priv) { + pkt_capture_err("packet capture vdev priv is NULL"); + goto release_vdev_ref; + } + + cb_ctx = vdev_priv->cb_ctx; + if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx) { + pkt_capture_err("mon cb params are NULL"); + goto release_vdev_ref; + } + + msdu = nbuf_list; + while (msdu) { + next_buf = qdf_nbuf_queue_next(msdu); + qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */ + if (QDF_STATUS_SUCCESS != + cb_ctx->mon_cb(cb_ctx->mon_ctx, msdu)) { + pkt_capture_err("Frame Rx to HDD failed"); + qdf_nbuf_free(msdu); + } + msdu = next_buf; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); + return; + +release_vdev_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); +free_buf: + drop_count = pkt_capture_drop_nbuf_list(nbuf_list); + pkt_capture_debug("Dropped frames %u", drop_count); +} + +/** + * pkt_capture_mgmtpkt_process() - process management packets + * for pkt capture mode + * @psoc: pointer to psoc object + * @txrx_status: mon_rx_status to update radiotap header + * @nbuf: netbuf + * @status: Tx status + * + * Return: QDF_STATUS Enumeration + */ +static QDF_STATUS +pkt_capture_mgmtpkt_process(struct wlan_objmgr_psoc *psoc, + struct mon_rx_status *txrx_status, + qdf_nbuf_t nbuf, uint8_t status) +{ + struct wlan_objmgr_vdev *vdev; + struct pkt_capture_mon_pkt *pkt; + uint32_t headroom; + + vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, + QDF_STA_MODE, + WLAN_PKT_CAPTURE_ID); + if (!vdev) { + pkt_capture_err("vdev is NULL"); + return QDF_STATUS_E_FAILURE; + } + + /* + * Calculate the headroom and adjust head to prepare radiotap header + */ + headroom = qdf_nbuf_headroom(nbuf); + qdf_nbuf_update_radiotap(txrx_status, nbuf, headroom); + + pkt = pkt_capture_alloc_mon_pkt(vdev); + if (!pkt) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); + return QDF_STATUS_E_FAILURE; + } + + pkt->callback = pkt_capture_mgmtpkt_cb; + pkt->context = psoc; + pkt->monpkt = nbuf; + pkt->vdev_id = WLAN_INVALID_VDEV_ID; + pkt->tid = WLAN_INVALID_TID; + pkt->status = status; + pkt->pkt_format = PKTCAPTURE_PKT_FORMAT_80211; + pkt_capture_indicate_monpkt(vdev, pkt); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_PKT_CAPTURE_ID); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev, + struct mgmt_offload_event_params *params, + qdf_nbuf_t nbuf, + uint8_t status) +{ + struct mon_rx_status txrx_status = {0}; + struct wlan_objmgr_psoc *psoc; + uint16_t channel_flags = 0; + tpSirMacFrameCtl pfc = (tpSirMacFrameCtl) (qdf_nbuf_data(nbuf)); + struct ieee80211_frame *wh; + uint8_t mgt_type; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) + return QDF_STATUS_E_FAILURE; + + wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); + mgt_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + + if (mgt_type == IEEE80211_FC0_TYPE_MGT && + (pfc->subType == SIR_MAC_MGMT_DISASSOC || + pfc->subType == SIR_MAC_MGMT_DEAUTH || + pfc->subType == SIR_MAC_MGMT_ACTION)) { + uint8_t *orig_hdr; + uint8_t mic_len, hdr_len, pdev_id; + + if (!QDF_IS_ADDR_BROADCAST(wh->i_addr1) && + !IEEE80211_IS_MULTICAST(wh->i_addr1)) { + if (pfc->wep) { + orig_hdr = (uint8_t *)qdf_nbuf_data(nbuf); + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + status = mlme_get_peer_mic_len(psoc, pdev_id, + wh->i_addr2, + &mic_len, + &hdr_len); + if (QDF_IS_STATUS_ERROR(status)) { + pkt_capture_err("Failed to get mic hdr"); + return QDF_STATUS_E_FAILURE; + } + + /* Strip privacy headers (and trailer) + * for a received frame + */ + qdf_mem_move(orig_hdr + + hdr_len, wh, + sizeof(*wh)); + qdf_nbuf_pull_head(nbuf, + hdr_len); + qdf_nbuf_trim_tail(nbuf, mic_len); + } + } else { + qdf_nbuf_trim_tail(nbuf, IEEE80211_MMIE_LEN); + } + } + + txrx_status.tsft = (u_int64_t)params->tsf_l32; + txrx_status.chan_num = wlan_freq_to_chan(params->chan_freq); + txrx_status.chan_freq = params->chan_freq; + /* params->rate is in Kbps, convert into Mbps */ + txrx_status.rate = (params->rate_kbps / 1000); + if (params->rssi == INVALID_RSSI_FOR_TX) + /* RSSI -128 is invalid rssi for TX, make it 0 here, + * will be normalized during radiotap updation + */ + txrx_status.ant_signal_db = 0; + else + txrx_status.ant_signal_db = params->rssi; + + txrx_status.rssi_comb = txrx_status.ant_signal_db; + txrx_status.nr_ant = 1; + txrx_status.rtap_flags |= + ((txrx_status.rate == 6 /* Mbps */) ? BIT(1) : 0); + channel_flags |= + ((txrx_status.rate == 6 /* Mbps */) ? + IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK); + channel_flags |= + (wlan_reg_chan_to_band(txrx_status.chan_num) == BAND_2G ? + IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ); + txrx_status.chan_flags = channel_flags; + txrx_status.rate = ((txrx_status.rate == 6 /* Mbps */) ? 0x0c : 0x02); + + wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); + wh->i_fc[1] &= ~IEEE80211_FC1_WEP; + + return pkt_capture_mgmtpkt_process(psoc, &txrx_status, + nbuf, status); +} + +void +pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, + uint32_t desc_id, + uint32_t status, + struct mgmt_offload_event_params *params) +{ + qdf_nbuf_t wbuf, nbuf; + int nbuf_len; + + if (!pdev) { + pkt_capture_err("pdev is NULL"); + return; + } + + nbuf = mgmt_txrx_get_nbuf(pdev, desc_id); + if (!nbuf) + return; + + nbuf_len = qdf_nbuf_len(nbuf); + wbuf = qdf_nbuf_alloc(NULL, roundup(nbuf_len + RESERVE_BYTES, 4), + RESERVE_BYTES, 4, false); + if (!wbuf) { + pkt_capture_err("Failed to allocate wbuf for mgmt len(%u)", + nbuf_len); + return; + } + + qdf_nbuf_put_tail(wbuf, nbuf_len); + qdf_mem_copy(qdf_nbuf_data(wbuf), qdf_nbuf_data(nbuf), nbuf_len); + + if (QDF_STATUS_SUCCESS != + pkt_capture_process_mgmt_tx_data(pdev, params, wbuf, status)) + qdf_nbuf_free(wbuf); +} + +/** + * process_pktcapture_mgmt_rx_data_cb() - process management rx packets + * @rx_params: mgmt rx event params + * @wbuf: netbuf + * + * Return: none + */ +static QDF_STATUS +pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, + qdf_nbuf_t wbuf, + struct mgmt_rx_event_params *rx_params, + enum mgmt_frame_type frm_type) +{ + struct mon_rx_status txrx_status = {0}; + uint16_t channel_flags = 0; + struct ieee80211_frame *wh; + qdf_nbuf_t nbuf; + int buf_len; + + if (!(pkt_capture_get_mode(psoc) & PKT_CAPTURE_MODE_MGMT_ONLY)) + return QDF_STATUS_E_FAILURE; + + buf_len = qdf_nbuf_len(wbuf); + nbuf = qdf_nbuf_alloc(NULL, roundup( + buf_len + RESERVE_BYTES, 4), + RESERVE_BYTES, 4, false); + if (!nbuf) + return QDF_STATUS_E_FAILURE; + + qdf_nbuf_put_tail(nbuf, buf_len); + qdf_mem_copy(qdf_nbuf_data(nbuf), qdf_nbuf_data(wbuf), buf_len); + + txrx_status.tsft = (u_int64_t)rx_params->tsf_delta; + txrx_status.chan_num = rx_params->channel; + txrx_status.chan_freq = wlan_chan_to_freq(txrx_status.chan_num); + /* rx_params->rate is in Kbps, convert into Mbps */ + txrx_status.rate = (rx_params->rate / 1000); + txrx_status.ant_signal_db = rx_params->snr; + txrx_status.rssi_comb = rx_params->snr; + txrx_status.chan_noise_floor = NORMALIZED_TO_NOISE_FLOOR; + txrx_status.nr_ant = 1; + txrx_status.rtap_flags |= + ((txrx_status.rate == 6 /* Mbps */) ? BIT(1) : 0); + channel_flags |= + ((txrx_status.rate == 6 /* Mbps */) ? + IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK); + channel_flags |= + (wlan_reg_chan_to_band(txrx_status.chan_num) == BAND_2G ? + IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ); + txrx_status.chan_flags = channel_flags; + txrx_status.rate = ((txrx_status.rate == 6 /* Mbps */) ? 0x0c : 0x02); + + wh = (struct ieee80211_frame *)qdf_nbuf_data(nbuf); + wh->i_fc[1] &= ~IEEE80211_FC1_WEP; + + if (QDF_STATUS_SUCCESS != + pkt_capture_mgmtpkt_process(psoc, &txrx_status, nbuf, 0)) + qdf_nbuf_free(nbuf); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS pkt_capture_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, + bool is_register) +{ + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; + QDF_STATUS status; + int num_of_entries; + + frm_cb_info.frm_type = MGMT_FRAME_TYPE_ALL; + frm_cb_info.mgmt_rx_cb = pkt_capture_mgmt_rx_data_cb; + num_of_entries = 1; + + if (is_register) + status = wlan_mgmt_txrx_register_rx_cb( + psoc, WLAN_UMAC_COMP_PKT_CAPTURE, + &frm_cb_info, num_of_entries); + else + status = wlan_mgmt_txrx_deregister_rx_cb( + psoc, WLAN_UMAC_COMP_PKT_CAPTURE, + &frm_cb_info, num_of_entries); + + return status; +} diff --git a/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_public_structs.h b/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_public_structs.h index 86f286c7bd437..3f16a670c3027 100644 --- a/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_public_structs.h +++ b/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_public_structs.h @@ -33,4 +33,27 @@ enum pkt_capture_mode { PACKET_CAPTURE_MODE_DATA_MGMT, }; +/** + * struct mgmt_offload_event_params - Management offload event params + * @tsf_l32: The lower 32 bits of the TSF + * @chan_freq: channel frequency in MHz + * @rate_kbps: Rate kbps + * @rssi: combined RSSI, i.e. the sum of the snr + noise floor (dBm units) + * @buf_len: length of the frame in bytes + * @tx_status: 0: xmit ok + * 1: excessive retries + * 2: blocked by tx filtering + * 4: fifo underrun + * 8: swabort + * @buf: management frame buffer + */ +struct mgmt_offload_event_params { + uint32_t tsf_l32; + uint32_t chan_freq; + uint32_t rate_kbps; + uint32_t rssi; + uint32_t buf_len; + uint32_t tx_status; + uint8_t *buf; +}; #endif /* _WLAN_PKT_CAPTURE_PUBLIC_STRUCTS_H_ */ diff --git a/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h b/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h index 90ffb5f8bfafe..14664005d464a 100644 --- a/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h +++ b/components/pkt_capture/dispatcher/inc/wlan_pkt_capture_ucfg_api.h @@ -115,6 +115,38 @@ void ucfg_pkt_capture_set_pktcap_mode(struct wlan_objmgr_psoc *psoc, */ enum pkt_capture_mode ucfg_pkt_capture_get_pktcap_mode(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_pkt_capture_process_mgmt_tx_data() - process management tx packets + * @pdev: pointer to pdev object + * @params: management offload event params + * @nbuf: netbuf + * @status: status + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev, + struct mgmt_offload_event_params *params, + qdf_nbuf_t nbuf, + uint8_t status); + +/** + * ucfg_pkt_capture_mgmt_tx_completion(): process mgmt tx completion + * for pkt capture mode + * @pdev: pointer to pdev object + * @desc_id: desc_id + * @status: status + * @params: management offload event params + * + * Return: none + */ +void +ucfg_pkt_capture_mgmt_tx_completion( + struct wlan_objmgr_pdev *pdev, + uint32_t desc_id, + uint32_t status, + struct mgmt_offload_event_params *params); #else static inline QDF_STATUS ucfg_pkt_capture_init(void) @@ -169,5 +201,22 @@ ucfg_pkt_capture_get_pktcap_mode(struct wlan_objmgr_psoc *psoc) { return PACKET_CAPTURE_MODE_DISABLE; } + +static inline QDF_STATUS +ucfg_pkt_capture_process_mgmt_tx_data( + struct mgmt_offload_event_params *params, + qdf_nbuf_t nbuf, + uint8_t status) +{ + return 0; +} + +static inline void +ucfg_pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, + uint32_t desc_id, + uint32_t status, + struct mgmt_offload_event_params *params) +{ +} #endif /* WLAN_FEATURE_PKT_CAPTURE */ #endif /* _WLAN_PKT_CAPTURE_UCFG_API_H_ */ diff --git a/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c b/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c index f87e2645a4113..8ad68a16aec5f 100644 --- a/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c +++ b/components/pkt_capture/dispatcher/src/wlan_pkt_capture_ucfg_api.c @@ -24,6 +24,7 @@ #include "wlan_pkt_capture_main.h" #include "wlan_pkt_capture_ucfg_api.h" #include "wlan_pkt_capture_mon_thread.h" +#include "wlan_pkt_capture_mgmt_txrx.h" enum pkt_capture_mode ucfg_pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc) { @@ -184,3 +185,40 @@ void ucfg_pkt_capture_resume_mon_thread(struct wlan_objmgr_vdev *vdev) { pkt_capture_resume_mon_thread(vdev); } + +/** + * ucfg_process_pktcapture_mgmt_tx_data() - process management tx packets + * @pdev: pointer to pdev object + * @params: management offload event params + * @nbuf: netbuf + * @status: status + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_pkt_capture_process_mgmt_tx_data(struct wlan_objmgr_pdev *pdev, + struct mgmt_offload_event_params *params, + qdf_nbuf_t nbuf, + uint8_t status) +{ + return pkt_capture_process_mgmt_tx_data(pdev, params, nbuf, status); +} + +/** + * ucfg_process_pktcapture_mgmt_tx_completion(): process mgmt tx completion + * for pkt capture mode + * @pdev: pointer to pdev object + * @desc_id: desc_id + * @status: status + * @params: management offload event params + * + * Return: none + */ +void +ucfg_pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev, + uint32_t desc_id, + uint32_t status, + struct mgmt_offload_event_params *params) +{ + pkt_capture_mgmt_tx_completion(pdev, desc_id, status, params); +} diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index b8d228295025c..2d884f4f6728c 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -79,6 +79,7 @@ #include #include #include <../../core/src/vdev_mgr_ops.h> +#include "wlan_pkt_capture_ucfg_api.h" #if !defined(REMOVE_PKT_LOG) #include @@ -2655,6 +2656,25 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle, return 0; } +/** + * wma_extract_mgmt_offload_event_params() - Extract mgmt event params + * @params: Management offload event params + * @hdr: Management header to extract + * + * Return: None + */ +static void wma_extract_mgmt_offload_event_params( + struct mgmt_offload_event_params *params, + wmi_mgmt_hdr *hdr) +{ + params->tsf_l32 = hdr->tsf_l32; + params->chan_freq = hdr->chan_freq; + params->rate_kbps = hdr->rate_kbps; + params->rssi = hdr->rssi; + params->buf_len = hdr->buf_len; + params->tx_status = hdr->tx_status; +} + /** * wma_mgmt_tx_completion_handler() - wma mgmt Tx completion event handler * @handle: wma handle @@ -2669,7 +2689,7 @@ int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params, { tp_wma_handle wma_handle = (tp_wma_handle)handle; WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf; - wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; + wmi_mgmt_tx_compl_event_fixed_param *cmpl_params; param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *) cmpl_event_params; @@ -2679,8 +2699,21 @@ int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params, } cmpl_params = param_buf->fixed_param; - wma_process_mgmt_tx_completion(wma_handle, - cmpl_params->desc_id, cmpl_params->status); + if (ucfg_pkt_capture_get_pktcap_mode(wma_handle->psoc) & + PKT_CAPTURE_MODE_MGMT_ONLY) { + struct mgmt_offload_event_params params = {0}; + + wma_extract_mgmt_offload_event_params( + ¶ms, + (wmi_mgmt_hdr *)param_buf->mgmt_hdr); + ucfg_pkt_capture_mgmt_tx_completion(wma_handle->pdev, + cmpl_params->desc_id, + cmpl_params->status, + ¶ms); + } + + wma_process_mgmt_tx_completion(wma_handle, cmpl_params->desc_id, + cmpl_params->status); return 0; } @@ -2740,9 +2773,22 @@ int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf, return -EINVAL; } - for (i = 0; i < num_reports; i++) + for (i = 0; i < num_reports; i++) { + if (ucfg_pkt_capture_get_pktcap_mode(wma_handle->psoc) & + PKT_CAPTURE_MODE_MGMT_ONLY) { + struct mgmt_offload_event_params params = {0}; + + wma_extract_mgmt_offload_event_params( + ¶ms, + &((wmi_mgmt_hdr *)param_buf->mgmt_hdr)[i]); + ucfg_pkt_capture_mgmt_tx_completion( + wma_handle->pdev, desc_ids[i], + status[i], ¶ms); + } + wma_process_mgmt_tx_completion(wma_handle, - desc_ids[i], status[i]); + desc_ids[i], status[i]); + } return 0; }