qcacld-3.0: Process Rx data packet for pkt capture mode

Process Rx data packets and post to the mon thread for
packet capture mode

Change-Id: Id8ae54677615c27d61c6def1a521c509f602863b
CRs-Fixed: 2618941
This commit is contained in:
Vulupala Shashank Reddy
2020-01-29 11:16:39 +05:30
committed by nshrivas
parent 5a3b87db75
commit a2deef8c83
14 changed files with 683 additions and 21 deletions

1
Kbuild
View File

@@ -1053,6 +1053,7 @@ 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)/core/src/wlan_pkt_capture_data_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

View File

@@ -0,0 +1,101 @@
/*
* 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 private API which shall be used internally only
* in pkt_capture component. This file shall include prototypes of
* pkt_capture data tx and data rx.
*
* Note: This API should be never accessed out of pkt_capture component.
*/
#ifndef _WLAN_PKT_CAPTURE_DATA_TXRX_H_
#define _WLAN_PKT_CAPTURE_DATA_TXRX_H_
#include "cdp_txrx_cmn_struct.h"
#include <ol_txrx_types.h>
#include <qdf_nbuf.h>
/**
* pkt_capture_data_process_type - data pkt types to process
* for packet capture mode
* @TXRX_PROCESS_TYPE_DATA_RX: process RX packets (normal rx + offloaded rx)
* @TXRX_PROCESS_TYPE_DATA_TX: process TX packets (ofloaded tx)
* @TXRX_PROCESS_TYPE_DATA_TX_COMPL: process TX compl packets (normal tx)
*/
enum pkt_capture_data_process_type {
TXRX_PROCESS_TYPE_DATA_RX,
TXRX_PROCESS_TYPE_DATA_TX,
TXRX_PROCESS_TYPE_DATA_TX_COMPL,
};
#define TXRX_PKTCAPTURE_PKT_FORMAT_8023 0
#define TXRX_PKTCAPTURE_PKT_FORMAT_80211 1
/**
* pkt_capture_datapkt_process() - process data tx and rx packets
* for pkt capture mode. (normal tx/rx + offloaded tx/rx)
* @vdev_id: vdev id for which packet is captured
* @mon_buf_list: netbuf list
* @type: data process type
* @tid: tid number
* @status: Tx status
* @pkt_format: Frame format
* @bssid: bssid
* @pdev: pdev handle
*
* Return: none
*/
void pkt_capture_datapkt_process(
uint8_t vdev_id,
qdf_nbuf_t mon_buf_list,
enum pkt_capture_data_process_type type,
uint8_t tid, uint8_t status, bool pkt_format,
uint8_t *bssid, htt_pdev_handle pdev);
/**
* pkt_capture_msdu_process_pkts() - process data rx pkts
* @bssid: bssid
* @head_msdu: pointer to head msdu
* @vdev_id: vdev_id
* @pdev: pdev handle
*
* Return: none
*/
void pkt_capture_msdu_process_pkts(
uint8_t *bssid,
qdf_nbuf_t head_msdu,
uint8_t vdev_id,
htt_pdev_handle pdev);
/**
* pkt_capture_rx_in_order_drop_offload_pkt() - drop offload packets
* @head_msdu: pointer to head msdu
*
* Return: none
*/
void pkt_capture_rx_in_order_drop_offload_pkt(qdf_nbuf_t head_msdu);
/**
* pkt_capture_rx_in_order_offloaded_pkt() - check offloaded data pkt or not
* @rx_ind_msg: rx_ind_msg
*
* Return: false, if it is not offload pkt
* true, if it is offload pkt
*/
bool pkt_capture_rx_in_order_offloaded_pkt(qdf_nbuf_t rx_ind_msg);
#endif /* End of _WLAN_PKT_CAPTURE_DATA_TXRX_H_ */

View File

@@ -30,6 +30,7 @@
#include <qdf_types.h>
#include "wlan_pkt_capture_priv.h"
#include "wlan_pkt_capture_objmgr.h"
#include "wlan_objmgr_vdev_obj.h"
#define pkt_capture_log(level, args...) \
QDF_TRACE(QDF_MODULE_ID_PKT_CAPTURE, level, ## args)
@@ -51,6 +52,13 @@
#define PKT_CAPTURE_ENTER() pkt_capture_debug("enter")
#define PKT_CAPTURE_EXIT() pkt_capture_debug("exit")
/**
* pkt_capture_get_vdev() - Get pkt capture objmgr vdev.
*
* Return: pkt capture objmgr vdev
*/
struct wlan_objmgr_vdev *pkt_capture_get_vdev(void);
/**
* pkt_capture_vdev_create_notification() - Handler for vdev create notify.
* @vdev: vdev which is going to be created by objmgr

View File

@@ -38,29 +38,35 @@
/* timeout in msec to wait for mon thread to suspend */
#define PKT_CAPTURE_SUSPEND_TIMEOUT 200
typedef void (*pkt_capture_mon_thread_cb)(void *context, void *monpkt,
typedef void (*pkt_capture_mon_thread_cb)(
void *context, void *ppdev, void *monpkt,
uint8_t vdev_id, uint8_t tid,
uint8_t status, bool pkt_format);
uint8_t status, bool pkt_format,
uint8_t *bssid);
/*
* struct pkt_capture_mon_pkt - mon packet wrapper for mon data from TXRX
* @list: List for storing mon packets
* @context: Callback context
* @pdev: pointer to pdev handle
* @monpkt: Mon skb
* @vdev_id: Vdev id to which this packet is destined
* @tid: Tid of mon packet
* @status: Tx packet status
* @pkt_format: Mon packet format, 0 = 802.3 format , 1 = 802.11 format
* @bssid: bssid
* @callback: Mon callback
*/
struct pkt_capture_mon_pkt {
struct list_head list;
void *context;
void *pdev;
void *monpkt;
uint8_t vdev_id;
uint8_t tid;
uint8_t status;
bool pkt_format;
uint8_t bssid[QDF_MAC_ADDR_SIZE];
pkt_capture_mon_thread_cb callback;
};

View File

@@ -0,0 +1,370 @@
/*
* 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 various notification handlers which are accessed
* internally in pkt_capture component only.
*/
#include <wlan_pkt_capture_data_txrx.h>
#include <wlan_pkt_capture_main.h>
#include <enet.h>
#include <htt_internal.h>
/**
* pkt_capture_rx_convert8023to80211() - convert 802.3 packet to 802.11
* format from rx desc
* @bssid: bssid
* @msdu: netbuf
* @desc: rx desc
*
* Return: none
*/
static void
pkt_capture_rx_convert8023to80211(uint8_t *bssid, qdf_nbuf_t msdu, void *desc)
{
struct ethernet_hdr_t *eth_hdr;
struct llc_snap_hdr_t *llc_hdr;
struct ieee80211_frame *wh;
uint8_t hdsize, new_hdsize;
struct ieee80211_qoscntl *qos_cntl;
uint16_t seq_no;
uint8_t localbuf[sizeof(struct ieee80211_qosframe_htc_addr4) +
sizeof(struct llc_snap_hdr_t)];
const uint8_t ethernet_II_llc_snap_header_prefix[] = {
0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
uint16_t ether_type;
struct htt_host_rx_desc_base *rx_desc = desc;
eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
hdsize = sizeof(struct ethernet_hdr_t);
wh = (struct ieee80211_frame *)localbuf;
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
*(uint16_t *)wh->i_dur = 0;
new_hdsize = 0;
/* DA , BSSID , SA */
qdf_mem_copy(wh->i_addr1, eth_hdr->dest_addr,
QDF_MAC_ADDR_SIZE);
qdf_mem_copy(wh->i_addr2, bssid,
QDF_MAC_ADDR_SIZE);
qdf_mem_copy(wh->i_addr3, eth_hdr->src_addr,
QDF_MAC_ADDR_SIZE);
wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
if (rx_desc->attention.more_data)
wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
if (rx_desc->attention.power_mgmt)
wh->i_fc[1] |= IEEE80211_FC1_PWR_MGT;
if (rx_desc->attention.fragment)
wh->i_fc[1] |= IEEE80211_FC1_MORE_FRAG;
if (rx_desc->attention.order)
wh->i_fc[1] |= IEEE80211_FC1_ORDER;
if (rx_desc->mpdu_start.retry)
wh->i_fc[1] |= IEEE80211_FC1_RETRY;
seq_no = rx_desc->mpdu_start.seq_num;
seq_no = (seq_no << IEEE80211_SEQ_SEQ_SHIFT) & IEEE80211_SEQ_SEQ_MASK;
qdf_mem_copy(wh->i_seq, &seq_no, sizeof(seq_no));
new_hdsize = sizeof(struct ieee80211_frame);
if (rx_desc->attention.non_qos == 0) {
qos_cntl =
(struct ieee80211_qoscntl *)(localbuf + new_hdsize);
qos_cntl->i_qos[0] =
(rx_desc->mpdu_start.tid & IEEE80211_QOS_TID);
wh->i_fc[0] |= QDF_IEEE80211_FC0_SUBTYPE_QOS;
qos_cntl->i_qos[1] = 0;
new_hdsize += sizeof(struct ieee80211_qoscntl);
}
/*
* Prepare llc Header
*/
llc_hdr = (struct llc_snap_hdr_t *)(localbuf + new_hdsize);
ether_type = (eth_hdr->ethertype[0] << 8) |
(eth_hdr->ethertype[1]);
if (ether_type >= ETH_P_802_3_MIN) {
qdf_mem_copy(llc_hdr,
ethernet_II_llc_snap_header_prefix,
sizeof
(ethernet_II_llc_snap_header_prefix));
if (ether_type == ETHERTYPE_AARP ||
ether_type == ETHERTYPE_IPX) {
llc_hdr->org_code[2] =
BTEP_SNAP_ORGCODE_2;
/* 0xf8; bridge tunnel header */
}
llc_hdr->ethertype[0] = eth_hdr->ethertype[0];
llc_hdr->ethertype[1] = eth_hdr->ethertype[1];
new_hdsize += sizeof(struct llc_snap_hdr_t);
}
/*
* Remove 802.3 Header by adjusting the head
*/
qdf_nbuf_pull_head(msdu, hdsize);
/*
* Adjust the head and prepare 802.11 Header
*/
qdf_nbuf_push_head(msdu, new_hdsize);
qdf_mem_copy(qdf_nbuf_data(msdu), localbuf, new_hdsize);
}
void pkt_capture_rx_in_order_drop_offload_pkt(qdf_nbuf_t head_msdu)
{
while (head_msdu) {
qdf_nbuf_t msdu = head_msdu;
head_msdu = qdf_nbuf_next(head_msdu);
qdf_nbuf_free(msdu);
}
}
bool pkt_capture_rx_in_order_offloaded_pkt(qdf_nbuf_t rx_ind_msg)
{
uint32_t *msg_word;
msg_word = (uint32_t *)qdf_nbuf_data(rx_ind_msg);
/* check if it is for offloaded data pkt */
return HTT_RX_IN_ORD_PADDR_IND_PKT_CAPTURE_MODE_IS_MONITOR_SET
(*(msg_word + 1));
}
void pkt_capture_msdu_process_pkts(
uint8_t *bssid,
qdf_nbuf_t head_msdu,
uint8_t vdev_id, htt_pdev_handle pdev)
{
qdf_nbuf_t loop_msdu, pktcapture_msdu;
qdf_nbuf_t msdu, prev = NULL;
pktcapture_msdu = NULL;
loop_msdu = head_msdu;
while (loop_msdu) {
msdu = qdf_nbuf_copy(loop_msdu);
if (msdu) {
qdf_nbuf_push_head(msdu,
HTT_RX_STD_DESC_RESERVATION);
qdf_nbuf_set_next(msdu, NULL);
if (!(pktcapture_msdu)) {
pktcapture_msdu = msdu;
prev = msdu;
} else {
qdf_nbuf_set_next(prev, msdu);
prev = msdu;
}
}
loop_msdu = qdf_nbuf_next(loop_msdu);
}
if (!pktcapture_msdu)
return;
pkt_capture_datapkt_process(
vdev_id, pktcapture_msdu,
TXRX_PROCESS_TYPE_DATA_RX, 0, 0,
TXRX_PKTCAPTURE_PKT_FORMAT_8023,
bssid, pdev);
}
/**
* pkt_capture_rx_data_cb(): callback to process data rx packets
* for pkt capture mode. (normal rx + offloaded rx)
* @context: objmgr vdev
* @ppdev: device handler
* @nbuf_list: netbuf list
* @vdev_id: vdev id for which packet is captured
* @tid: tid number
* @status: Tx status
* @pkt_format: Frame format
* @bssid: bssid
*
* Return: none
*/
static void
pkt_capture_rx_data_cb(
void *context, void *ppdev, void *nbuf_list,
uint8_t vdev_id, uint8_t tid,
uint8_t status, bool pkt_format,
uint8_t *bssid)
{
struct pkt_capture_vdev_priv *vdev_priv;
qdf_nbuf_t buf_list = (qdf_nbuf_t)nbuf_list;
struct wlan_objmgr_vdev *vdev = context;
htt_pdev_handle pdev = ppdev;
struct pkt_capture_cb_context *cb_ctx;
qdf_nbuf_t msdu, next_buf;
uint8_t drop_count;
struct htt_host_rx_desc_base *rx_desc;
struct mon_rx_status rx_status = {0};
uint32_t headroom;
static uint8_t preamble_type;
static uint32_t vht_sig_a_1;
static uint32_t vht_sig_a_2;
vdev_priv = pkt_capture_vdev_get_priv(vdev);
if (qdf_unlikely(!vdev))
goto free_buf;
cb_ctx = vdev_priv->cb_ctx;
if (!cb_ctx || !cb_ctx->mon_cb || !cb_ctx->mon_ctx)
goto free_buf;
msdu = buf_list;
while (msdu) {
struct ethernet_hdr_t *eth_hdr;
next_buf = qdf_nbuf_queue_next(msdu);
qdf_nbuf_set_next(msdu, NULL); /* Add NULL terminator */
rx_desc = htt_rx_desc(msdu);
/*
* Only the first mpdu has valid preamble type, so use it
* till the last mpdu is reached
*/
if (rx_desc->attention.first_mpdu) {
preamble_type = rx_desc->ppdu_start.preamble_type;
if (preamble_type == 8 || preamble_type == 9 ||
preamble_type == 0x0c || preamble_type == 0x0d) {
vht_sig_a_1 = VHT_SIG_A_1(rx_desc);
vht_sig_a_2 = VHT_SIG_A_2(rx_desc);
}
} else {
rx_desc->ppdu_start.preamble_type = preamble_type;
if (preamble_type == 8 || preamble_type == 9 ||
preamble_type == 0x0c || preamble_type == 0x0d) {
VHT_SIG_A_1(rx_desc) = vht_sig_a_1;
VHT_SIG_A_2(rx_desc) = vht_sig_a_2;
}
}
if (rx_desc->attention.last_mpdu) {
preamble_type = 0;
vht_sig_a_1 = 0;
vht_sig_a_2 = 0;
}
qdf_nbuf_pull_head(msdu, HTT_RX_STD_DESC_RESERVATION);
/*
* Get the channel info and update the rx status
*/
/* need to update this to fill rx_status*/
htt_rx_mon_get_rx_status(pdev, rx_desc, &rx_status);
rx_status.chan_noise_floor = NORMALIZED_TO_NOISE_FLOOR;
/* clear IEEE80211_RADIOTAP_F_FCS flag*/
rx_status.rtap_flags &= ~(BIT(4));
rx_status.rtap_flags &= ~(BIT(2));
/*
* convert 802.3 header format into 802.11 format
*/
if (vdev_id == HTT_INVALID_VDEV) {
eth_hdr = (struct ethernet_hdr_t *)qdf_nbuf_data(msdu);
qdf_mem_copy(bssid, eth_hdr->src_addr,
QDF_MAC_ADDR_SIZE);
}
pkt_capture_rx_convert8023to80211(bssid, msdu, rx_desc);
/*
* Calculate the headroom and adjust head
* to prepare radiotap header.
*/
headroom = qdf_nbuf_headroom(msdu);
qdf_nbuf_update_radiotap(&rx_status, msdu, headroom);
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;
}
return;
free_buf:
drop_count = pkt_capture_drop_nbuf_list(buf_list);
}
void pkt_capture_datapkt_process(
uint8_t vdev_id,
qdf_nbuf_t mon_buf_list,
enum pkt_capture_data_process_type type,
uint8_t tid, uint8_t status, bool pkt_format,
uint8_t *bssid, htt_pdev_handle pdev)
{
uint8_t drop_count;
struct pkt_capture_mon_pkt *pkt;
pkt_capture_mon_thread_cb callback = NULL;
struct wlan_objmgr_vdev *vdev;
vdev = pkt_capture_get_vdev();
if (!vdev)
goto drop_rx_buf;
pkt = pkt_capture_alloc_mon_pkt(vdev);
if (!pkt)
goto drop_rx_buf;
switch (type) {
case TXRX_PROCESS_TYPE_DATA_RX:
callback = pkt_capture_rx_data_cb;
break;
case TXRX_PROCESS_TYPE_DATA_TX:
break;
case TXRX_PROCESS_TYPE_DATA_TX_COMPL:
break;
default:
return;
}
pkt->callback = callback;
pkt->context = (void *)vdev;
pkt->pdev = (void *)pdev;
pkt->monpkt = (void *)mon_buf_list;
pkt->vdev_id = vdev_id;
pkt->tid = tid;
pkt->status = status;
pkt->pkt_format = pkt_format;
qdf_mem_copy(pkt->bssid, bssid, QDF_MAC_ADDR_SIZE);
pkt_capture_indicate_monpkt(vdev, pkt);
return;
drop_rx_buf:
drop_count = pkt_capture_drop_nbuf_list(mon_buf_list);
}

View File

@@ -27,6 +27,13 @@
#include "wlan_pkt_capture_mgmt_txrx.h"
#include "target_if_pkt_capture.h"
static struct wlan_objmgr_vdev *gp_pkt_capture_vdev;
struct wlan_objmgr_vdev *pkt_capture_get_vdev()
{
return gp_pkt_capture_vdev;
}
enum pkt_capture_mode pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc)
{
struct pkt_psoc_priv *psoc_priv;
@@ -296,6 +303,7 @@ pkt_capture_vdev_create_notification(struct wlan_objmgr_vdev *vdev, void *arg)
}
vdev_priv->vdev = vdev;
gp_pkt_capture_vdev = vdev;
status = pkt_capture_callback_ctx_create(vdev_priv);
if (!QDF_IS_STATUS_SUCCESS(status)) {
@@ -366,6 +374,7 @@ pkt_capture_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg)
pkt_capture_mon_context_destroy(vdev_priv);
pkt_capture_callback_ctx_destroy(vdev_priv);
qdf_mem_free(vdev_priv);
gp_pkt_capture_vdev = NULL;
return status;
}

View File

@@ -44,9 +44,9 @@
* Return: none
*/
static void
pkt_capture_mgmtpkt_cb(void *context, void *nbuf_list,
pkt_capture_mgmtpkt_cb(void *context, void *ppdev, void *nbuf_list,
uint8_t vdev_id, uint8_t tid, uint8_t status,
bool pkt_format)
bool pkt_format, uint8_t *bssid)
{
struct pkt_capture_vdev_priv *vdev_priv;
struct wlan_objmgr_psoc *psoc = context;
@@ -293,7 +293,7 @@ pkt_capture_mgmt_rx_data_cb(struct wlan_objmgr_psoc *psoc,
qdf_nbuf_t nbuf;
int buf_len;
if (!(pkt_capture_get_mode(psoc) & PKT_CAPTURE_MODE_MGMT_ONLY))
if (!(pkt_capture_get_pktcap_mode(psoc) & PKT_CAPTURE_MODE_MGMT_ONLY))
return QDF_STATUS_E_FAILURE;
buf_len = qdf_nbuf_len(wbuf);

View File

@@ -209,8 +209,8 @@ pkt_capture_process_from_queue(struct pkt_capture_mon_context *mon_ctx)
spin_unlock_bh(&mon_ctx->mon_queue_lock);
vdev_id = pkt->vdev_id;
tid = pkt->tid;
pkt->callback(pkt->context, pkt->monpkt, vdev_id,
tid, pkt->status, pkt->pkt_format);
pkt->callback(pkt->context, pkt->pdev, pkt->monpkt, vdev_id,
tid, pkt->status, pkt->pkt_format, pkt->bssid);
pkt_capture_free_mon_pkt(mon_ctx, pkt);
spin_lock_bh(&mon_ctx->mon_queue_lock);
}

View File

@@ -28,6 +28,8 @@
#include <qdf_types.h>
#include "wlan_pkt_capture_objmgr.h"
#include "wlan_pkt_capture_public_structs.h"
#include "wlan_pkt_capture_mon_thread.h"
#include <htt_types.h>
#ifdef WLAN_FEATURE_PKT_CAPTURE
/**
@@ -155,6 +157,38 @@ ucfg_pkt_capture_mgmt_tx_completion(
* Return: 0 on success, -EINVAL on failure
*/
int ucfg_pkt_capture_enable_ops(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_pkt_capture_rx_msdu_process() - process data rx pkts
* @bssid: bssid
* @head_msdu: pointer to head msdu
* @vdev_id: vdev_id
* @pdev: pdev handle
*
* Return: none
*/
void ucfg_pkt_capture_rx_msdu_process(
uint8_t *bssid,
qdf_nbuf_t head_msdu,
uint8_t vdev_id, htt_pdev_handle pdev);
/**
* ucfg_pkt_capture_rx_offloaded_pkt() - check offloaded data pkt or not
* @rx_ind_msg: rx_ind_msg
*
* Return: 0 not an offload pkt
* 1 offload pkt
*/
bool ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg);
/**
* ucfg_pkt_capture_rx_drop_offload_pkt() - drop offload packets
* @head_msdu: pointer to head msdu
*
* Return: none
*/
void ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu);
#else
static inline
QDF_STATUS ucfg_pkt_capture_init(void)
@@ -226,5 +260,24 @@ ucfg_pkt_capture_mgmt_tx_completion(struct wlan_objmgr_pdev *pdev,
struct mgmt_offload_event_params *params)
{
}
static inline void
ucfg_pkt_capture_rx_msdu_process(
uint8_t *bssid,
qdf_nbuf_t head_msdu,
uint8_t vdev_id, htt_pdev_handle pdev)
{
}
static inline bool
ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg)
{
return false;
}
static inline void
ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu)
{
}
#endif /* WLAN_FEATURE_PKT_CAPTURE */
#endif /* _WLAN_PKT_CAPTURE_UCFG_API_H_ */

View File

@@ -26,6 +26,7 @@
#include "wlan_pkt_capture_mon_thread.h"
#include "wlan_pkt_capture_mgmt_txrx.h"
#include "target_if_pkt_capture.h"
#include "wlan_pkt_capture_data_txrx.h"
enum pkt_capture_mode ucfg_pkt_capture_get_mode(struct wlan_objmgr_psoc *psoc)
{
@@ -271,3 +272,22 @@ int ucfg_pkt_capture_enable_ops(struct wlan_objmgr_vdev *vdev)
return 0;
}
void ucfg_pkt_capture_rx_msdu_process(
uint8_t *bssid,
qdf_nbuf_t head_msdu,
uint8_t vdev_id, htt_pdev_handle pdev)
{
pkt_capture_msdu_process_pkts(bssid, head_msdu,
vdev_id, pdev);
}
bool ucfg_pkt_capture_rx_offloaded_pkt(qdf_nbuf_t rx_ind_msg)
{
return pkt_capture_rx_in_order_offloaded_pkt(rx_ind_msg);
}
void ucfg_pkt_capture_rx_drop_offload_pkt(qdf_nbuf_t head_msdu)
{
pkt_capture_rx_in_order_drop_offload_pkt(head_msdu);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2014-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2011, 2014-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
@@ -1119,6 +1119,19 @@ int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
qdf_nbuf_t *head_msdu,
qdf_nbuf_t *tail_msdu,
uint32_t *replenish_cnt);
/**
* htt_rx_mon_get_rx_status() - Update information about the rx status,
* which is used later for radiotap updation.
* @pdev: Pointer to pdev handle
* @rx_desc: Pointer to struct htt_host_rx_desc_base
* @rx_status: Return variable updated with rx_status
*
* Return: None
*/
void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
struct htt_host_rx_desc_base *rx_desc,
struct mon_rx_status *rx_status);
#else
static inline
int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
@@ -1129,6 +1142,13 @@ int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
{
return 0;
}
static inline
void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
struct htt_host_rx_desc_base *rx_desc,
struct mon_rx_status *rx_status)
{
}
#endif
#endif /* _HTT_INTERNAL__H_ */

View File

@@ -458,15 +458,7 @@ static uint8_t htt_mon_rx_get_rtap_flags(struct htt_host_rx_desc_base *rx_desc)
return rtap_flags;
}
/**
* htt_rx_mon_get_rx_status() - Update information about the rx status,
* which is used later for radiotap updation.
* @rx_desc: Pointer to struct htt_host_rx_desc_base
* @rx_status: Return variable updated with rx_status
*
* Return: None
*/
static void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
void htt_rx_mon_get_rx_status(htt_pdev_handle pdev,
struct htt_host_rx_desc_base *rx_desc,
struct mon_rx_status *rx_status)
{

View File

@@ -56,6 +56,7 @@
#include <cdp_txrx_handle.h>
#include <pld_common.h>
#include <htt_internal.h>
#include <wlan_pkt_capture_ucfg_api.h>
#ifndef OL_RX_INDICATION_MAX_RECORDS
#define OL_RX_INDICATION_MAX_RECORDS 2048
@@ -1561,6 +1562,7 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
{
struct ol_txrx_vdev_t *vdev = NULL;
struct ol_txrx_peer_t *peer = NULL;
struct ol_txrx_peer_t *peer_head = NULL;
htt_pdev_handle htt_pdev = NULL;
int status;
qdf_nbuf_t head_msdu = NULL, tail_msdu = NULL;
@@ -1569,6 +1571,14 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
uint32_t msdu_count;
uint8_t pktlog_bit;
uint32_t filled = 0;
uint8_t bssid[QDF_MAC_ADDR_SIZE];
bool offloaded_pkt;
struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC);
if (qdf_unlikely(!soc)) {
ol_txrx_err("soc is NULL");
return;
}
if (tid >= OL_TXRX_NUM_EXT_TIDS) {
ol_txrx_err("invalid tid, %u", tid);
@@ -1632,6 +1642,43 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
/* rx_opt_proc takes a NULL-terminated list of msdu netbufs */
qdf_nbuf_set_next(tail_msdu, NULL);
/* Packet Capture Mode */
if ((ucfg_pkt_capture_get_mode((void *)soc->psoc) &
PKT_CAPTURE_MODE_DATA_ONLY)) {
offloaded_pkt = ucfg_pkt_capture_rx_offloaded_pkt(rx_ind_msg);
if (peer) {
vdev = peer->vdev;
if (peer->vdev) {
qdf_spin_lock_bh(&pdev->peer_ref_mutex);
peer_head = TAILQ_FIRST(&vdev->peer_list);
qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
if (peer_head) {
qdf_spin_lock_bh(
&peer_head->peer_info_lock);
qdf_mem_copy(bssid,
&peer_head->mac_addr.raw,
QDF_MAC_ADDR_SIZE);
qdf_spin_unlock_bh(
&peer_head->peer_info_lock);
ucfg_pkt_capture_rx_msdu_process(
bssid, head_msdu,
peer->vdev->vdev_id,
htt_pdev);
}
}
} else if (offloaded_pkt) {
ucfg_pkt_capture_rx_msdu_process(
bssid, head_msdu,
HTT_INVALID_VDEV,
htt_pdev);
ucfg_pkt_capture_rx_drop_offload_pkt(head_msdu);
return;
}
}
/* Pktlog */
ol_rx_send_pktlog_event(pdev, peer, head_msdu, pktlog_bit);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2011-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
@@ -58,6 +58,7 @@
#include <ol_rx_defrag.h>
#include <enet.h>
#include <qdf_time.h> /* qdf_system_time */
#include <wlan_pkt_capture_ucfg_api.h>
#define DEFRAG_IEEE80211_ADDR_EQ(a1, a2) \
(!qdf_mem_cmp(a1, a2, QDF_MAC_ADDR_SIZE))
@@ -653,7 +654,14 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev,
struct ieee80211_frame *wh;
uint8_t key[DEFRAG_IEEE80211_KEY_LEN];
htt_pdev_handle htt_pdev = pdev->htt_pdev;
struct ol_txrx_peer_t *peer_head = NULL;
uint8_t bssid[QDF_MAC_ADDR_SIZE];
struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC);
if (qdf_unlikely(!soc)) {
ol_txrx_err("soc is NULL");
return;
}
vdev = peer->vdev;
/* bypass defrag for safe mode */
@@ -770,6 +778,33 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev,
if (ol_cfg_frame_type(pdev->ctrl_pdev) == wlan_frm_fmt_802_3)
ol_rx_defrag_nwifi_to_8023(pdev, msdu);
/* Packet Capture Mode */
if ((ucfg_pkt_capture_get_mode((void *)soc->psoc) &
PKT_CAPTURE_MODE_DATA_ONLY)) {
if (peer) {
if (peer->vdev) {
qdf_spin_lock_bh(&pdev->peer_ref_mutex);
peer_head = TAILQ_FIRST(&vdev->peer_list);
qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
if (peer_head) {
qdf_spin_lock_bh(
&peer_head->peer_info_lock);
qdf_mem_copy(bssid,
&peer_head->mac_addr.raw,
QDF_MAC_ADDR_SIZE);
qdf_spin_unlock_bh(
&peer_head->peer_info_lock);
ucfg_pkt_capture_rx_msdu_process(
bssid, msdu,
vdev->vdev_id,
htt_pdev);
}
}
}
}
ol_rx_fwd_check(vdev, peer, tid, msdu);
}