qcacmn: Tx packet capture
Add support to send MSDU, mgmt. and ctrl payload along with metadata to upper layer callback FR 42132 Change-Id: Ie751322c7c15419ea908538e9e8687b64693fcfa CRs-Fixed:2068486
This commit is contained in:

gecommit door
snandini

bovenliggende
f6cb4b8576
commit
cfbb8952ff
@@ -531,6 +531,15 @@ struct cdp_soc_t {
|
||||
struct ol_if_ops *ol_ops;
|
||||
};
|
||||
|
||||
/*
|
||||
* cdp_pdev_param_type: different types of parameters
|
||||
* to set values in pdev
|
||||
* @CDP_ENABLE_TX_CAPTURE: Enable Tx capture feature
|
||||
*/
|
||||
enum cdp_pdev_param_type {
|
||||
CDP_CONFIG_TX_CAPTURE,
|
||||
};
|
||||
|
||||
/*
|
||||
* cdp_vdev_param_type: different types of parameters
|
||||
* to set values in vdev
|
||||
|
@@ -389,6 +389,16 @@ cdp_peer_set_nawds(ol_txrx_soc_handle soc,
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void cdp_txrx_set_pdev_param(ol_txrx_soc_handle soc,
|
||||
struct cdp_pdev *pdev, enum cdp_pdev_param_type type,
|
||||
uint8_t val)
|
||||
{
|
||||
if (soc->ops->ctrl_ops->txrx_set_pdev_param)
|
||||
return soc->ops->ctrl_ops->txrx_set_pdev_param
|
||||
(pdev, type, val);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Subscribe to a specified WDI event.
|
||||
* @details
|
||||
|
@@ -415,6 +415,9 @@ struct cdp_ctrl_ops {
|
||||
|
||||
void (*txrx_update_mgmt_txpow_vdev)(struct cdp_vdev *vdev,
|
||||
uint8_t subtype, uint8_t tx_power);
|
||||
|
||||
void (*txrx_set_pdev_param)(struct cdp_pdev *pdev,
|
||||
enum cdp_pdev_param_type type, uint8_t val);
|
||||
};
|
||||
|
||||
struct cdp_me_ops {
|
||||
|
@@ -44,6 +44,8 @@ do { \
|
||||
htt_htc_misc_pkt_list_add(soc, pkt); \
|
||||
} while (0)
|
||||
|
||||
#define HTT_MGMT_CTRL_TLV_RESERVERD_LEN 12
|
||||
|
||||
/*
|
||||
* dp_tx_stats_update() - Update per-peer statistics
|
||||
* @soc: Datapath soc handle
|
||||
@@ -1789,6 +1791,42 @@ static void dp_process_ppdu_stats_user_common_array_tlv(struct dp_pdev *pdev,
|
||||
HTT_PPDU_STATS_ARRAY_ITEM_TLV_TX_DUR_GET(*tag_buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv: Process
|
||||
* htt_ppdu_stats_tx_mgmtctrl_payload_tlv
|
||||
* @pdev: DP PDEV handle
|
||||
* @tag_buf: buffer containing the htt_ppdu_stats_tx_mgmtctrl_payload_tlv
|
||||
* @length: tlv_length
|
||||
*
|
||||
* return:void
|
||||
*/
|
||||
static void dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(
|
||||
struct dp_pdev *pdev, uint32_t *tag_buf, uint32_t length)
|
||||
{
|
||||
htt_ppdu_stats_tx_mgmtctrl_payload_tlv *dp_stats_buf =
|
||||
(htt_ppdu_stats_tx_mgmtctrl_payload_tlv *)tag_buf;
|
||||
|
||||
qdf_nbuf_t nbuf = NULL;
|
||||
|
||||
uint32_t payload_size = length - HTT_MGMT_CTRL_TLV_RESERVERD_LEN;
|
||||
|
||||
nbuf = qdf_nbuf_alloc(pdev->soc->osdev, payload_size, 0, 4, true);
|
||||
|
||||
if (!nbuf) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"Nbuf Allocation failed for Mgmt. payload");
|
||||
qdf_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_nbuf_put_tail(nbuf, payload_size);
|
||||
qdf_mem_copy(qdf_nbuf_data(nbuf), dp_stats_buf->payload, payload_size);
|
||||
|
||||
dp_wdi_event_handler(WDI_EVENT_TX_MGMT_CTRL, pdev->soc,
|
||||
nbuf, HTT_INVALID_PEER,
|
||||
WDI_NO_VAL, pdev->pdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_process_ppdu_tag(): Function to process the PPDU TLVs
|
||||
* @soc: DP Physical device (radio) handle
|
||||
@@ -1838,6 +1876,10 @@ static void dp_process_ppdu_tag(struct dp_pdev *pdev, uint32_t *tag_buf,
|
||||
dp_process_ppdu_stats_user_common_array_tlv(pdev,
|
||||
tag_buf);
|
||||
break;
|
||||
case HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV:
|
||||
dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(pdev,
|
||||
tag_buf, tlv_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1908,7 +1950,7 @@ static void dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
|
||||
int status;
|
||||
int i;
|
||||
|
||||
if (!pdev->enhanced_stats_en)
|
||||
if (!pdev->enhanced_stats_en && !pdev->tx_sniffer_enable)
|
||||
return;
|
||||
|
||||
if (!pdev->tx_ppdu_info.buf) {
|
||||
|
@@ -4795,6 +4795,30 @@ dp_ppdu_ring_cfg(struct dp_pdev *pdev)
|
||||
RX_BUFFER_SIZE, &htt_tlv_filter);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_config_tx_capture()- API to enable/disable tx capture
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
* @val: user provided value
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void
|
||||
dp_config_tx_capture(struct cdp_pdev *pdev_handle, int val)
|
||||
{
|
||||
struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
|
||||
|
||||
if (val) {
|
||||
pdev->tx_sniffer_enable = 1;
|
||||
dp_h2t_cfg_stats_msg_send(pdev, 0xffff);
|
||||
} else {
|
||||
pdev->tx_sniffer_enable = 0;
|
||||
|
||||
if (!pdev->enhanced_stats_en)
|
||||
dp_h2t_cfg_stats_msg_send(pdev, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_enable_enhanced_stats()- API to enable enhanced statistcs
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
@@ -4821,7 +4845,11 @@ static void
|
||||
dp_disable_enhanced_stats(struct cdp_pdev *pdev_handle)
|
||||
{
|
||||
struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
|
||||
|
||||
pdev->enhanced_stats_en = 0;
|
||||
|
||||
if (!pdev->tx_sniffer_enable)
|
||||
dp_h2t_cfg_stats_msg_send(pdev, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4866,6 +4894,26 @@ dp_get_fw_peer_stats(struct cdp_pdev *pdev_handle, uint8_t *mac_addr,
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_set_pdev_param: function to set parameters in pdev
|
||||
* @pdev_handle: DP pdev handle
|
||||
* @param: parameter type to be set
|
||||
* @val: value of parameter to be set
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
static void dp_set_pdev_param(struct cdp_pdev *pdev_handle,
|
||||
enum cdp_pdev_param_type param, uint8_t val)
|
||||
{
|
||||
switch (param) {
|
||||
case CDP_CONFIG_TX_CAPTURE:
|
||||
dp_config_tx_capture(pdev_handle, val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_set_vdev_param: function to set parameters in vdev
|
||||
* @param: parameter type to be set
|
||||
@@ -5374,6 +5422,7 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
|
||||
/* TODO: Add other functions */
|
||||
.txrx_wdi_event_sub = dp_wdi_event_sub,
|
||||
.txrx_wdi_event_unsub = dp_wdi_event_unsub,
|
||||
.txrx_set_pdev_param = dp_set_pdev_param,
|
||||
};
|
||||
|
||||
static struct cdp_me_ops dp_ops_me = {
|
||||
|
@@ -1731,6 +1731,56 @@ static void dp_tx_inspect_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
||||
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
|
||||
}
|
||||
|
||||
#ifdef FEATURE_PERPKT_INFO
|
||||
static QDF_STATUS
|
||||
dp_send_compl_to_stack(struct dp_soc *soc, struct dp_tx_desc_s *desc,
|
||||
uint16_t peer_id, uint16_t ppdu_id)
|
||||
{
|
||||
struct tx_capture_hdr *ppdu_hdr;
|
||||
struct ethhdr *eh;
|
||||
struct dp_peer *peer = NULL;
|
||||
qdf_nbuf_t netbuf = desc->nbuf;
|
||||
|
||||
if (!desc->pdev->tx_sniffer_enable)
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
|
||||
eh = (struct ethhdr *)(netbuf->data);
|
||||
peer = (peer_id == HTT_INVALID_PEER) ? NULL :
|
||||
dp_peer_find_by_id(soc, peer_id);
|
||||
|
||||
if (!peer) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("Peer Invalid"));
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (!qdf_nbuf_push_head(netbuf, sizeof(struct tx_capture_hdr))) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("No headroom"));
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
ppdu_hdr = (struct tx_capture_hdr *)qdf_nbuf_data(netbuf);
|
||||
qdf_mem_copy(ppdu_hdr->ta, (eh->h_dest), IEEE80211_ADDR_LEN);
|
||||
ppdu_hdr->ppdu_id = ppdu_id;
|
||||
qdf_mem_copy(ppdu_hdr->ra, peer->mac_addr.raw,
|
||||
IEEE80211_ADDR_LEN);
|
||||
|
||||
dp_wdi_event_handler(WDI_EVENT_TX_DATA, soc,
|
||||
netbuf, peer_id,
|
||||
WDI_NO_VAL, desc->pdev->pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static QDF_STATUS
|
||||
dp_send_compl_to_stack(struct dp_soc *soc, struct dp_tx_desc_s *desc,
|
||||
uint16_t peer_id, uint16_t ppdu_id)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_tx_comp_free_buf() - Free nbuf associated with the Tx Descriptor
|
||||
* @soc: Soc handle
|
||||
@@ -1743,6 +1793,10 @@ static inline void dp_tx_comp_free_buf(struct dp_soc *soc,
|
||||
{
|
||||
struct dp_vdev *vdev = desc->vdev;
|
||||
qdf_nbuf_t nbuf = desc->nbuf;
|
||||
struct hal_tx_completion_status ts = {0};
|
||||
|
||||
if (desc)
|
||||
hal_tx_comp_get_status(&desc->comp, &ts);
|
||||
|
||||
/* If it is TDLS mgmt, don't unmap or free the frame */
|
||||
if (desc->flags & DP_TX_DESC_FLAG_TDLS_FRAME)
|
||||
@@ -1769,6 +1823,9 @@ static inline void dp_tx_comp_free_buf(struct dp_soc *soc,
|
||||
|
||||
qdf_nbuf_unmap(soc->osdev, nbuf, QDF_DMA_TO_DEVICE);
|
||||
|
||||
if (dp_send_compl_to_stack(soc, desc, ts.peer_id, ts.ppdu_id))
|
||||
return;
|
||||
|
||||
if (!vdev->mesh_vdev) {
|
||||
qdf_nbuf_free(nbuf);
|
||||
} else {
|
||||
|
@@ -1046,6 +1046,8 @@ struct dp_pdev {
|
||||
uint8_t last_user;
|
||||
qdf_nbuf_t buf;
|
||||
} tx_ppdu_info;
|
||||
|
||||
bool tx_sniffer_enable;
|
||||
};
|
||||
|
||||
struct dp_peer;
|
||||
|
Verwijs in nieuw issue
Block a user