qcacmn: Add support for tx monitor full buffer and minor fix
Add support and handle tx monitor full buffer payload and other minior fix include change of name for uniformity. Change-Id: If401ecd5e1c6263584fa7013df672459c883ca8b CRs-Fixed: 3215244
This commit is contained in:

committed by
Madan Koyyalamudi

parent
af37507eba
commit
09bc440ca9
@@ -1287,8 +1287,8 @@ dp_mon_register_feature_ops_2_0(struct dp_soc *soc)
|
||||
mon_ops->mon_tx_capture_debugfs_init = NULL;
|
||||
mon_ops->mon_tx_add_to_comp_queue = NULL;
|
||||
mon_ops->mon_print_pdev_tx_capture_stats =
|
||||
dp_print_pdev_tx_capture_stats_2_0;
|
||||
mon_ops->mon_config_enh_tx_capture = dp_config_enh_tx_capture_2_0;
|
||||
dp_print_pdev_tx_monitor_stats_2_0;
|
||||
mon_ops->mon_config_enh_tx_capture = dp_config_enh_tx_monitor_2_0;
|
||||
mon_ops->mon_tx_peer_filter = dp_peer_set_tx_capture_enabled_2_0;
|
||||
#endif
|
||||
#if (defined(WIFI_MONITOR_SUPPORT) && !defined(WLAN_TX_PKT_CAPTURE_ENH_BE))
|
||||
@@ -1296,7 +1296,7 @@ dp_mon_register_feature_ops_2_0(struct dp_soc *soc)
|
||||
mon_ops->mon_tx_capture_debugfs_init = NULL;
|
||||
mon_ops->mon_tx_add_to_comp_queue = NULL;
|
||||
mon_ops->mon_print_pdev_tx_capture_stats = NULL;
|
||||
mon_ops->mon_config_enh_tx_capture = dp_config_enh_tx_core_capture_2_0;
|
||||
mon_ops->mon_config_enh_tx_capture = dp_config_enh_tx_core_monitor_2_0;
|
||||
mon_ops->mon_tx_peer_filter = NULL;
|
||||
#endif
|
||||
#ifdef WLAN_RX_PKT_CAPTURE_ENH
|
||||
|
@@ -136,7 +136,7 @@ struct dp_mon_desc_pool {
|
||||
* @filter_be: filters sent to fw
|
||||
* @tx_mon_mode: tx monitor mode
|
||||
* @tx_mon_filter_length: tx monitor filter length
|
||||
* @tx_capture: pointer to tx capture function
|
||||
* @tx_monitor_be: pointer to tx monitor be structure
|
||||
* @tx_stats: tx monitor drop stats
|
||||
* @rx_mon_wq_lock: Rx mon workqueue lock
|
||||
* @rx_mon_workqueue: Rx mon workqueue
|
||||
@@ -151,7 +151,7 @@ struct dp_mon_pdev_be {
|
||||
struct dp_mon_filter_be **filter_be;
|
||||
uint8_t tx_mon_mode;
|
||||
uint8_t tx_mon_filter_length;
|
||||
struct dp_pdev_tx_capture_be tx_capture_be;
|
||||
struct dp_pdev_tx_monitor_be tx_monitor_be;
|
||||
struct dp_tx_monitor_drop_stats tx_stats;
|
||||
qdf_spinlock_t rx_mon_wq_lock;
|
||||
qdf_workqueue_t *rx_mon_workqueue;
|
||||
|
@@ -46,10 +46,9 @@ dp_tx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
|
||||
uint32_t work_done = 0;
|
||||
struct dp_mon_soc *mon_soc = soc->monitor_soc;
|
||||
struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
|
||||
union dp_mon_desc_list_elem_t *desc_list = NULL;
|
||||
union dp_mon_desc_list_elem_t *tail = NULL;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be = NULL;
|
||||
struct dp_mon_desc_pool *tx_mon_desc_pool = &mon_soc_be->tx_desc_mon;
|
||||
uint32_t tx_monitor_reap_cnt = 0;
|
||||
struct dp_tx_mon_desc_list mon_desc_list;
|
||||
|
||||
if (!pdev) {
|
||||
dp_mon_err("%pK: pdev is null for mac_id = %d", soc, mac_id);
|
||||
@@ -69,11 +68,15 @@ dp_tx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return work_done;
|
||||
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
hal_soc = soc->hal_soc;
|
||||
|
||||
qdf_assert((hal_soc && pdev));
|
||||
|
||||
qdf_spin_lock_bh(&mon_pdev->mon_lock);
|
||||
mon_desc_list.desc_list = NULL;
|
||||
mon_desc_list.tail = NULL;
|
||||
mon_desc_list.tx_mon_reap_cnt = 0;
|
||||
|
||||
if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_dst_srng))) {
|
||||
dp_mon_err("%s %d : HAL Mon Dest Ring access Failed -- %pK",
|
||||
@@ -87,7 +90,8 @@ dp_tx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
|
||||
&& quota--)) {
|
||||
struct hal_mon_desc hal_mon_tx_desc = {0};
|
||||
struct dp_mon_desc *mon_desc = NULL;
|
||||
uint32_t end_offset = DP_MON_DATA_BUFFER_SIZE;
|
||||
qdf_frag_t status_frag = NULL;
|
||||
uint32_t end_offset = 0;
|
||||
|
||||
hal_be_get_mon_dest_status(soc->hal_soc,
|
||||
tx_mon_dst_ring_desc,
|
||||
@@ -136,27 +140,19 @@ dp_tx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
|
||||
qdf_assert_always(0);
|
||||
}
|
||||
|
||||
if (qdf_likely(hal_mon_tx_desc.end_offset))
|
||||
end_offset = hal_mon_tx_desc.end_offset;
|
||||
|
||||
if ((hal_mon_tx_desc.end_reason == HAL_MON_FLUSH_DETECTED) ||
|
||||
(hal_mon_tx_desc.end_reason == HAL_MON_PPDU_TRUNCATED)) {
|
||||
dp_tx_mon_update_end_reason(mon_pdev,
|
||||
hal_mon_tx_desc.ppdu_id,
|
||||
hal_mon_tx_desc.end_reason);
|
||||
|
||||
qdf_frag_free(mon_desc->buf_addr);
|
||||
status_frag = (qdf_frag_t)(mon_desc->buf_addr);
|
||||
mon_desc->buf_addr = NULL;
|
||||
++tx_monitor_reap_cnt;
|
||||
dp_mon_add_to_free_desc_list(&desc_list,
|
||||
&tail, mon_desc);
|
||||
/* increment reap count */
|
||||
++mon_desc_list.tx_mon_reap_cnt;
|
||||
|
||||
work_done++;
|
||||
hal_srng_dst_get_next(hal_soc, mon_dst_srng);
|
||||
continue;
|
||||
}
|
||||
/* add the mon_desc to free list */
|
||||
dp_mon_add_to_free_desc_list(&mon_desc_list.desc_list,
|
||||
&mon_desc_list.tail, mon_desc);
|
||||
|
||||
if (qdf_unlikely(!mon_desc->buf_addr)) {
|
||||
|
||||
if (qdf_unlikely(!status_frag)) {
|
||||
dp_mon_debug("P_ID:%d INIT:%d E_DESC:%d R_ID:%d L_CNT:%d BUF_ADDR: 0x%llx E_OFF: %d E_REA: %d",
|
||||
hal_mon_tx_desc.ppdu_id,
|
||||
hal_mon_tx_desc.initiator,
|
||||
@@ -167,9 +163,22 @@ dp_tx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
|
||||
hal_mon_tx_desc.end_offset,
|
||||
hal_mon_tx_desc.end_reason);
|
||||
|
||||
++tx_monitor_reap_cnt;
|
||||
dp_mon_add_to_free_desc_list(&desc_list,
|
||||
&tail, mon_desc);
|
||||
work_done++;
|
||||
hal_srng_dst_get_next(hal_soc, mon_dst_srng);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((hal_mon_tx_desc.end_reason == HAL_MON_FLUSH_DETECTED) ||
|
||||
(hal_mon_tx_desc.end_reason == HAL_MON_PPDU_TRUNCATED)) {
|
||||
tx_mon_be->be_ppdu_id = hal_mon_tx_desc.ppdu_id;
|
||||
dp_tx_mon_update_end_reason(mon_pdev,
|
||||
hal_mon_tx_desc.ppdu_id,
|
||||
hal_mon_tx_desc.end_reason);
|
||||
/* check and free packet buffer from status buffer */
|
||||
dp_tx_mon_status_free_packet_buf(pdev, status_frag,
|
||||
end_offset,
|
||||
&mon_desc_list);
|
||||
qdf_frag_free(status_frag);
|
||||
|
||||
work_done++;
|
||||
hal_srng_dst_get_next(hal_soc, mon_dst_srng);
|
||||
@@ -178,26 +187,26 @@ dp_tx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
|
||||
|
||||
dp_tx_mon_process_status_tlv(soc, pdev,
|
||||
&hal_mon_tx_desc,
|
||||
mon_desc->buf_addr, end_offset);
|
||||
|
||||
mon_desc->buf_addr = NULL;
|
||||
++tx_monitor_reap_cnt;
|
||||
dp_mon_add_to_free_desc_list(&desc_list, &tail, mon_desc);
|
||||
status_frag,
|
||||
end_offset,
|
||||
&mon_desc_list);
|
||||
|
||||
work_done++;
|
||||
hal_srng_dst_get_next(hal_soc, mon_dst_srng);
|
||||
}
|
||||
dp_srng_access_end(int_ctx, soc, mon_dst_srng);
|
||||
|
||||
if (tx_monitor_reap_cnt) {
|
||||
if (mon_desc_list.tx_mon_reap_cnt) {
|
||||
dp_mon_buffers_replenish(soc, &mon_soc_be->tx_mon_buf_ring,
|
||||
tx_mon_desc_pool,
|
||||
tx_monitor_reap_cnt,
|
||||
&desc_list, &tail);
|
||||
mon_desc_list.tx_mon_reap_cnt,
|
||||
&mon_desc_list.desc_list,
|
||||
&mon_desc_list.tail);
|
||||
}
|
||||
qdf_spin_unlock_bh(&mon_pdev->mon_lock);
|
||||
dp_mon_debug("mac_id: %d, work_done:%d tx_monitor_reap_cnt:%d",
|
||||
mac_id, work_done, tx_monitor_reap_cnt);
|
||||
mac_id, work_done, mon_desc_list.tx_mon_reap_cnt);
|
||||
|
||||
return work_done;
|
||||
}
|
||||
|
||||
@@ -304,15 +313,18 @@ dp_tx_mon_buffers_alloc(struct dp_soc *soc, uint32_t size)
|
||||
}
|
||||
|
||||
#ifdef WLAN_TX_PKT_CAPTURE_ENH_BE
|
||||
|
||||
/*
|
||||
* dp_tx_mon_free_usr_mpduq() - API to free user mpduq
|
||||
* @tx_ppdu_info - pointer to tx_ppdu_info
|
||||
* @usr_idx - user index
|
||||
* @tx_mon_be - pointer to tx capture be
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void dp_tx_mon_free_usr_mpduq(struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
uint8_t usr_idx)
|
||||
uint8_t usr_idx,
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be)
|
||||
{
|
||||
qdf_nbuf_queue_t *mpdu_q;
|
||||
|
||||
@@ -320,16 +332,18 @@ void dp_tx_mon_free_usr_mpduq(struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
return;
|
||||
|
||||
mpdu_q = &TXMON_PPDU_USR(tx_ppdu_info, usr_idx, mpdu_q);
|
||||
qdf_nbuf_queue_remove(mpdu_q);
|
||||
qdf_nbuf_queue_free(mpdu_q);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_tx_mon_free_ppdu_info() - API to free dp_tx_ppdu_info
|
||||
* @tx_ppdu_info - pointer to tx_ppdu_info
|
||||
* @tx_mon_be - pointer to tx capture be
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void dp_tx_mon_free_ppdu_info(struct dp_tx_ppdu_info *tx_ppdu_info)
|
||||
void dp_tx_mon_free_ppdu_info(struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be)
|
||||
{
|
||||
uint32_t user = 0;
|
||||
|
||||
@@ -361,37 +375,12 @@ struct dp_tx_ppdu_info *dp_tx_mon_get_ppdu_info(struct dp_pdev *pdev,
|
||||
struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be =
|
||||
dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be =
|
||||
&mon_pdev_be->tx_capture_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be =
|
||||
&mon_pdev_be->tx_monitor_be;
|
||||
struct dp_tx_ppdu_info *tx_ppdu_info;
|
||||
size_t sz_ppdu_info = 0;
|
||||
uint8_t i;
|
||||
|
||||
if (type == TX_PROT_PPDU_INFO) {
|
||||
tx_ppdu_info = tx_cap_be->tx_prot_ppdu_info;
|
||||
if (tx_ppdu_info &&
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) != 1) {
|
||||
return tx_ppdu_info;
|
||||
} else if (tx_ppdu_info) {
|
||||
dp_tx_mon_free_ppdu_info(tx_ppdu_info);
|
||||
tx_ppdu_info = NULL;
|
||||
}
|
||||
|
||||
/* for protection frame num_user is always 1 */
|
||||
num_user = 1;
|
||||
} else {
|
||||
tx_ppdu_info = tx_cap_be->tx_data_ppdu_info;
|
||||
if (tx_ppdu_info &&
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) != 1 &&
|
||||
num_user == TXMON_PPDU_HAL(tx_ppdu_info, num_users)) {
|
||||
/* number of user matched */
|
||||
return tx_ppdu_info;
|
||||
} else if (tx_ppdu_info) {
|
||||
dp_tx_mon_free_ppdu_info(tx_ppdu_info);
|
||||
tx_ppdu_info = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate new tx_ppdu_info */
|
||||
sz_ppdu_info = (sizeof(struct dp_tx_ppdu_info) +
|
||||
(sizeof(struct mon_rx_user_status) * num_user));
|
||||
@@ -406,23 +395,21 @@ struct dp_tx_ppdu_info *dp_tx_mon_get_ppdu_info(struct dp_pdev *pdev,
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 0;
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, num_users) = num_user;
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, ppdu_id) = ppdu_id;
|
||||
tx_ppdu_info->ppdu_id = ppdu_id;
|
||||
|
||||
for (i = 0; i < num_user; i++) {
|
||||
qdf_nbuf_queue_t *mpdu_q;
|
||||
|
||||
mpdu_q = &TXMON_PPDU_USR(tx_ppdu_info, i, mpdu_q);
|
||||
if (qdf_unlikely(qdf_nbuf_queue_len(mpdu_q)))
|
||||
qdf_nbuf_queue_free(mpdu_q);
|
||||
|
||||
qdf_nbuf_queue_init(mpdu_q);
|
||||
}
|
||||
|
||||
/* assign tx_ppdu_info to monitor pdev for reference */
|
||||
if (type == TX_PROT_PPDU_INFO) {
|
||||
tx_cap_be->tx_prot_ppdu_info = tx_ppdu_info;
|
||||
tx_mon_be->tx_prot_ppdu_info = tx_ppdu_info;
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_data) = 0;
|
||||
} else {
|
||||
tx_cap_be->tx_data_ppdu_info = tx_ppdu_info;
|
||||
tx_mon_be->tx_data_ppdu_info = tx_ppdu_info;
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_data) = 1;
|
||||
}
|
||||
|
||||
@@ -430,37 +417,37 @@ struct dp_tx_ppdu_info *dp_tx_mon_get_ppdu_info(struct dp_pdev *pdev,
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_print_pdev_tx_capture_stats_2_0: print tx capture stats
|
||||
* dp_print_pdev_tx_monitor_stats_2_0: print tx capture stats
|
||||
* @pdev: DP PDEV handle
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void dp_print_pdev_tx_capture_stats_2_0(struct dp_pdev *pdev)
|
||||
void dp_print_pdev_tx_monitor_stats_2_0(struct dp_pdev *pdev)
|
||||
{
|
||||
/* TX monitor stats needed for beryllium */
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_config_enh_tx_capture_be()- API to enable/disable enhanced tx capture
|
||||
* dp_config_enh_tx_monitor_2_0()- API to enable/disable enhanced tx capture
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
* @val: user provided value
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
dp_config_enh_tx_capture_2_0(struct dp_pdev *pdev, uint8_t val)
|
||||
dp_config_enh_tx_monitor_2_0(struct dp_pdev *pdev, uint8_t val)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be =
|
||||
dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be =
|
||||
&mon_pdev_be->tx_capture_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be =
|
||||
&mon_pdev_be->tx_monitor_be;
|
||||
|
||||
switch (val) {
|
||||
case TX_MON_BE_DISABLE:
|
||||
{
|
||||
/* TODO: send HTT msg to configure TLV based on mode */
|
||||
tx_cap_be->mode = TX_MON_BE_DISABLE;
|
||||
tx_mon_be->mode = TX_MON_BE_DISABLE;
|
||||
mon_pdev_be->tx_mon_mode = 0;
|
||||
mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_64B;
|
||||
break;
|
||||
@@ -468,15 +455,15 @@ dp_config_enh_tx_capture_2_0(struct dp_pdev *pdev, uint8_t val)
|
||||
case TX_MON_BE_FULL_CAPTURE:
|
||||
{
|
||||
/* TODO: send HTT msg to configure TLV based on mode */
|
||||
tx_cap_be->mode = TX_MON_BE_FULL_CAPTURE;
|
||||
tx_mon_be->mode = TX_MON_BE_FULL_CAPTURE;
|
||||
mon_pdev_be->tx_mon_mode = 1;
|
||||
mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_256B;
|
||||
mon_pdev_be->tx_mon_filter_length = DEFAULT_DMA_LENGTH;
|
||||
break;
|
||||
}
|
||||
case TX_MON_BE_PEER_FILTER:
|
||||
{
|
||||
/* TODO: send HTT msg to configure TLV based on mode */
|
||||
tx_cap_be->mode = TX_MON_BE_PEER_FILTER;
|
||||
tx_mon_be->mode = TX_MON_BE_PEER_FILTER;
|
||||
mon_pdev_be->tx_mon_mode = 1;
|
||||
mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_256B;
|
||||
break;
|
||||
@@ -489,7 +476,7 @@ dp_config_enh_tx_capture_2_0(struct dp_pdev *pdev, uint8_t val)
|
||||
}
|
||||
|
||||
dp_mon_info("Tx monitor mode:%d mon_mode_flag:%d config_length:%d",
|
||||
tx_cap_be->mode, mon_pdev_be->tx_mon_mode,
|
||||
tx_mon_be->mode, mon_pdev_be->tx_mon_mode,
|
||||
mon_pdev_be->tx_mon_filter_length);
|
||||
|
||||
dp_mon_filter_setup_tx_mon_mode(pdev);
|
||||
@@ -545,14 +532,14 @@ static void dp_fill_lite_mon_vdev(struct cdp_tx_indication_info *tx_cap_info,
|
||||
static void
|
||||
dp_tx_mon_send_to_stack(struct dp_pdev *pdev, qdf_nbuf_t mpdu)
|
||||
{
|
||||
struct cdp_tx_indication_info tx_capture_info;
|
||||
struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be =
|
||||
dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
|
||||
struct cdp_tx_indication_info tx_capture_info = {0};
|
||||
|
||||
qdf_mem_set(&tx_capture_info,
|
||||
sizeof(struct cdp_tx_indication_info),
|
||||
0);
|
||||
tx_capture_info.radiotap_done = 1;
|
||||
tx_capture_info.mpdu_nbuf = mpdu;
|
||||
if (!dp_lite_mon_is_tx_enabled(pdev->monitor_pdev)) {
|
||||
if (!dp_lite_mon_is_tx_enabled(mon_pdev)) {
|
||||
dp_wdi_event_handler(WDI_EVENT_TX_PKT_CAPTURE,
|
||||
pdev->soc,
|
||||
&tx_capture_info,
|
||||
@@ -568,6 +555,8 @@ dp_tx_mon_send_to_stack(struct dp_pdev *pdev, qdf_nbuf_t mpdu)
|
||||
WDI_NO_VAL,
|
||||
pdev->pdev_id);
|
||||
}
|
||||
if (tx_capture_info.mpdu_nbuf)
|
||||
qdf_nbuf_free(tx_capture_info.mpdu_nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -575,73 +564,28 @@ dp_tx_mon_send_to_stack(struct dp_pdev *pdev, qdf_nbuf_t mpdu)
|
||||
* @pdev: pdev Handle
|
||||
* @ppdu_info: pointer to dp_tx_ppdu_info
|
||||
* @user_id: current user index
|
||||
* @radiota_hdr_ref: pointer to radiotap ref
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void
|
||||
dp_tx_mon_send_per_usr_mpdu(struct dp_pdev *pdev,
|
||||
struct dp_tx_ppdu_info *ppdu_info,
|
||||
uint8_t user_id,
|
||||
qdf_nbuf_t *radiotap_hdr_ref)
|
||||
uint8_t user_idx)
|
||||
{
|
||||
uint32_t mpdu_queue_len = 0;
|
||||
qdf_nbuf_queue_t *usr_mpdu_q = NULL;
|
||||
qdf_nbuf_t buf = NULL;
|
||||
qdf_nbuf_t radiotap_copy = NULL;
|
||||
|
||||
usr_mpdu_q = &TXMON_PPDU_USR(ppdu_info, user_id, mpdu_q);
|
||||
|
||||
if (!usr_mpdu_q) {
|
||||
qdf_nbuf_free(*radiotap_hdr_ref);
|
||||
*radiotap_hdr_ref = NULL;
|
||||
/* free radiotap hdr */
|
||||
return;
|
||||
}
|
||||
usr_mpdu_q = &TXMON_PPDU_USR(ppdu_info, user_idx, mpdu_q);
|
||||
|
||||
while ((buf = qdf_nbuf_queue_remove(usr_mpdu_q)) != NULL) {
|
||||
mpdu_queue_len = qdf_nbuf_queue_len(usr_mpdu_q);
|
||||
/*
|
||||
* In an aggregated frame, each mpdu is send individualy to
|
||||
* stack. caller of the function already allocate
|
||||
* and update radiotap header information. We copy the
|
||||
* same radiotap header until we reach the end of mpdu.
|
||||
* Once we reached end of mpdu we use the buffer allocated
|
||||
* for radiotap hdr.
|
||||
*/
|
||||
if (mpdu_queue_len) {
|
||||
radiotap_copy = qdf_nbuf_copy_expand(*radiotap_hdr_ref,
|
||||
0, 0);
|
||||
} else {
|
||||
radiotap_copy = *radiotap_hdr_ref;
|
||||
*radiotap_hdr_ref = NULL;
|
||||
ppdu_info->hal_txmon.rx_status.rx_user_status =
|
||||
&ppdu_info->hal_txmon.rx_user_status[user_idx];
|
||||
|
||||
qdf_nbuf_update_radiotap(&ppdu_info->hal_txmon.rx_status,
|
||||
buf, qdf_nbuf_headroom(buf));
|
||||
|
||||
dp_tx_mon_send_to_stack(pdev, buf);
|
||||
}
|
||||
|
||||
/* add msdu as a fraglist of mpdu */
|
||||
qdf_nbuf_append_ext_list(radiotap_copy,
|
||||
buf, qdf_nbuf_len(buf));
|
||||
dp_tx_mon_send_to_stack(pdev, radiotap_copy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_mon_alloc_radiotap_hdr() - API to allocate radiotap header
|
||||
* @pdev: pdev Handle
|
||||
* @nbuf_ref: reference to nbuf
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS
|
||||
dp_tx_mon_alloc_radiotap_hdr(struct dp_pdev *pdev, qdf_nbuf_t *nbuf_ref)
|
||||
{
|
||||
*nbuf_ref = qdf_nbuf_alloc(pdev->soc->osdev,
|
||||
MAX_MONITOR_HEADER,
|
||||
MAX_MONITOR_HEADER,
|
||||
4, FALSE);
|
||||
if (!*nbuf_ref)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -655,13 +599,8 @@ static void
|
||||
dp_tx_mon_update_radiotap(struct dp_pdev *pdev,
|
||||
struct dp_tx_ppdu_info *ppdu_info)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t usr_idx = 0;
|
||||
uint32_t num_users = 0;
|
||||
qdf_nbuf_t radiotap_hdr = NULL;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
|
||||
mon_pdev = pdev->monitor_pdev;
|
||||
|
||||
num_users = TXMON_PPDU_HAL(ppdu_info, num_users);
|
||||
|
||||
@@ -673,13 +612,15 @@ dp_tx_mon_update_radiotap(struct dp_pdev *pdev,
|
||||
TXMON_PPDU_COM(ppdu_info, chan_freq) =
|
||||
pdev->operating_channel.freq;
|
||||
|
||||
for (i = 0; i < num_users; i++) {
|
||||
/* allocate radiotap_hdr */
|
||||
status = dp_tx_mon_alloc_radiotap_hdr(pdev, &radiotap_hdr);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
/* free ppdu_info per user */
|
||||
dp_tx_mon_free_usr_mpduq(ppdu_info, i);
|
||||
continue;
|
||||
for (usr_idx = 0; usr_idx < num_users; usr_idx++) {
|
||||
qdf_nbuf_queue_t *mpdu_q = NULL;
|
||||
|
||||
/* set AMPDU flag if number mpdu is more than 1 */
|
||||
mpdu_q = &TXMON_PPDU_USR(ppdu_info, usr_idx, mpdu_q);
|
||||
if (mpdu_q && (qdf_nbuf_queue_len(mpdu_q) > 1)) {
|
||||
TXMON_PPDU_COM(ppdu_info,
|
||||
rs_flags) |= IEEE80211_AMPDU_FLAG;
|
||||
TXMON_PPDU_USR(ppdu_info, usr_idx, is_ampdu) = 1;
|
||||
}
|
||||
|
||||
if (qdf_unlikely(!TXMON_PPDU_COM(ppdu_info, rate))) {
|
||||
@@ -689,7 +630,7 @@ dp_tx_mon_update_radiotap(struct dp_pdev *pdev,
|
||||
|
||||
rate = dp_getrateindex(TXMON_PPDU_COM(ppdu_info, sgi),
|
||||
TXMON_PPDU_USR(ppdu_info,
|
||||
i, mcs),
|
||||
usr_idx, mcs),
|
||||
TXMON_PPDU_COM(ppdu_info, nss),
|
||||
TXMON_PPDU_COM(ppdu_info,
|
||||
preamble_type),
|
||||
@@ -701,21 +642,7 @@ dp_tx_mon_update_radiotap(struct dp_pdev *pdev,
|
||||
TXMON_PPDU_COM(ppdu_info, rate) = rate;
|
||||
}
|
||||
|
||||
/* copy rx_status to rx_status and invoke update radiotap */
|
||||
ppdu_info->hal_txmon.rx_status.rx_user_status =
|
||||
&ppdu_info->hal_txmon.rx_user_status[i];
|
||||
qdf_nbuf_update_radiotap(&ppdu_info->hal_txmon.rx_status,
|
||||
radiotap_hdr, MAX_MONITOR_HEADER);
|
||||
|
||||
/* radiotap header will be free in below function */
|
||||
dp_tx_mon_send_per_usr_mpdu(pdev, ppdu_info, i, &radiotap_hdr);
|
||||
|
||||
/*
|
||||
* radiotap_hdr will be free in above function
|
||||
* if not free here
|
||||
*/
|
||||
if (!!radiotap_hdr)
|
||||
qdf_nbuf_free(radiotap_hdr);
|
||||
dp_tx_mon_send_per_usr_mpdu(pdev, ppdu_info, usr_idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,7 +659,7 @@ void dp_tx_mon_ppdu_process(void *context)
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_tx_ppdu_info *defer_ppdu_info = NULL;
|
||||
struct dp_tx_ppdu_info *defer_ppdu_info_next = NULL;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
|
||||
/* sanity check */
|
||||
if (qdf_unlikely(!pdev))
|
||||
@@ -747,34 +674,34 @@ void dp_tx_mon_ppdu_process(void *context)
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
if (qdf_unlikely(TX_MON_BE_DISABLE == tx_cap_be->mode &&
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
if (qdf_unlikely(TX_MON_BE_DISABLE == tx_mon_be->mode &&
|
||||
!dp_lite_mon_is_tx_enabled(mon_pdev)))
|
||||
return;
|
||||
|
||||
/* take lock here */
|
||||
qdf_spin_lock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
STAILQ_CONCAT(&tx_cap_be->defer_tx_ppdu_info_queue,
|
||||
&tx_cap_be->tx_ppdu_info_queue);
|
||||
tx_cap_be->defer_ppdu_info_list_depth +=
|
||||
tx_cap_be->tx_ppdu_info_list_depth;
|
||||
tx_cap_be->tx_ppdu_info_list_depth = 0;
|
||||
qdf_spin_unlock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
qdf_spin_lock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
STAILQ_CONCAT(&tx_mon_be->defer_tx_ppdu_info_queue,
|
||||
&tx_mon_be->tx_ppdu_info_queue);
|
||||
tx_mon_be->defer_ppdu_info_list_depth +=
|
||||
tx_mon_be->tx_ppdu_info_list_depth;
|
||||
tx_mon_be->tx_ppdu_info_list_depth = 0;
|
||||
qdf_spin_unlock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
|
||||
STAILQ_FOREACH_SAFE(defer_ppdu_info,
|
||||
&tx_cap_be->defer_tx_ppdu_info_queue,
|
||||
&tx_mon_be->defer_tx_ppdu_info_queue,
|
||||
tx_ppdu_info_queue_elem, defer_ppdu_info_next) {
|
||||
/* remove dp_tx_ppdu_info from the list */
|
||||
STAILQ_REMOVE(&tx_cap_be->defer_tx_ppdu_info_queue,
|
||||
STAILQ_REMOVE(&tx_mon_be->defer_tx_ppdu_info_queue,
|
||||
defer_ppdu_info,
|
||||
dp_tx_ppdu_info,
|
||||
tx_ppdu_info_queue_elem);
|
||||
tx_cap_be->defer_ppdu_info_list_depth--;
|
||||
tx_mon_be->defer_ppdu_info_list_depth--;
|
||||
|
||||
dp_tx_mon_update_radiotap(pdev, defer_ppdu_info);
|
||||
|
||||
/* free the ppdu_info */
|
||||
dp_tx_mon_free_ppdu_info(defer_ppdu_info);
|
||||
dp_tx_mon_free_ppdu_info(defer_ppdu_info, tx_mon_be);
|
||||
defer_ppdu_info = NULL;
|
||||
}
|
||||
}
|
||||
@@ -789,7 +716,7 @@ void dp_tx_ppdu_stats_attach_2_0(struct dp_pdev *pdev)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
|
||||
if (qdf_unlikely(!pdev))
|
||||
return;
|
||||
@@ -803,20 +730,20 @@ void dp_tx_ppdu_stats_attach_2_0(struct dp_pdev *pdev)
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
|
||||
STAILQ_INIT(&tx_cap_be->tx_ppdu_info_queue);
|
||||
tx_cap_be->tx_ppdu_info_list_depth = 0;
|
||||
STAILQ_INIT(&tx_mon_be->tx_ppdu_info_queue);
|
||||
tx_mon_be->tx_ppdu_info_list_depth = 0;
|
||||
|
||||
STAILQ_INIT(&tx_cap_be->defer_tx_ppdu_info_queue);
|
||||
tx_cap_be->defer_ppdu_info_list_depth = 0;
|
||||
STAILQ_INIT(&tx_mon_be->defer_tx_ppdu_info_queue);
|
||||
tx_mon_be->defer_ppdu_info_list_depth = 0;
|
||||
|
||||
qdf_spinlock_create(&tx_cap_be->tx_mon_list_lock);
|
||||
qdf_spinlock_create(&tx_mon_be->tx_mon_list_lock);
|
||||
/* Work queue setup for TX MONITOR post handling */
|
||||
qdf_create_work(0, &tx_cap_be->post_ppdu_work,
|
||||
qdf_create_work(0, &tx_mon_be->post_ppdu_work,
|
||||
dp_tx_mon_ppdu_process, pdev);
|
||||
|
||||
tx_cap_be->post_ppdu_workqueue =
|
||||
tx_mon_be->post_ppdu_workqueue =
|
||||
qdf_alloc_unbound_workqueue("tx_mon_ppdu_work_queue");
|
||||
}
|
||||
|
||||
@@ -830,7 +757,7 @@ void dp_tx_ppdu_stats_detach_2_0(struct dp_pdev *pdev)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct dp_tx_ppdu_info *tx_ppdu_info = NULL;
|
||||
struct dp_tx_ppdu_info *tx_ppdu_info_next = NULL;
|
||||
|
||||
@@ -846,86 +773,86 @@ void dp_tx_ppdu_stats_detach_2_0(struct dp_pdev *pdev)
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
/* TODO: disable tx_monitor, to avoid further packet from HW */
|
||||
dp_monitor_config_enh_tx_capture(pdev, TX_MON_BE_DISABLE);
|
||||
|
||||
/* flush workqueue */
|
||||
qdf_flush_workqueue(0, tx_cap_be->post_ppdu_workqueue);
|
||||
qdf_destroy_workqueue(0, tx_cap_be->post_ppdu_workqueue);
|
||||
qdf_flush_workqueue(0, tx_mon_be->post_ppdu_workqueue);
|
||||
qdf_destroy_workqueue(0, tx_mon_be->post_ppdu_workqueue);
|
||||
|
||||
/*
|
||||
* TODO: iterate both tx_ppdu_info and defer_ppdu_info_list
|
||||
* free the tx_ppdu_info and decrement depth
|
||||
*/
|
||||
qdf_spin_lock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
qdf_spin_lock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
STAILQ_FOREACH_SAFE(tx_ppdu_info,
|
||||
&tx_cap_be->tx_ppdu_info_queue,
|
||||
&tx_mon_be->tx_ppdu_info_queue,
|
||||
tx_ppdu_info_queue_elem, tx_ppdu_info_next) {
|
||||
/* remove dp_tx_ppdu_info from the list */
|
||||
STAILQ_REMOVE(&tx_cap_be->tx_ppdu_info_queue, tx_ppdu_info,
|
||||
STAILQ_REMOVE(&tx_mon_be->tx_ppdu_info_queue, tx_ppdu_info,
|
||||
dp_tx_ppdu_info, tx_ppdu_info_queue_elem);
|
||||
/* decrement list length */
|
||||
tx_cap_be->tx_ppdu_info_list_depth--;
|
||||
tx_mon_be->tx_ppdu_info_list_depth--;
|
||||
/* free tx_ppdu_info */
|
||||
dp_tx_mon_free_ppdu_info(tx_ppdu_info);
|
||||
dp_tx_mon_free_ppdu_info(tx_ppdu_info, tx_mon_be);
|
||||
}
|
||||
qdf_spin_unlock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
qdf_spin_unlock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
|
||||
qdf_spin_lock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
qdf_spin_lock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
STAILQ_FOREACH_SAFE(tx_ppdu_info,
|
||||
&tx_cap_be->defer_tx_ppdu_info_queue,
|
||||
&tx_mon_be->defer_tx_ppdu_info_queue,
|
||||
tx_ppdu_info_queue_elem, tx_ppdu_info_next) {
|
||||
/* remove dp_tx_ppdu_info from the list */
|
||||
STAILQ_REMOVE(&tx_cap_be->defer_tx_ppdu_info_queue,
|
||||
STAILQ_REMOVE(&tx_mon_be->defer_tx_ppdu_info_queue,
|
||||
tx_ppdu_info,
|
||||
dp_tx_ppdu_info, tx_ppdu_info_queue_elem);
|
||||
/* decrement list length */
|
||||
tx_cap_be->defer_ppdu_info_list_depth--;
|
||||
tx_mon_be->defer_ppdu_info_list_depth--;
|
||||
/* free tx_ppdu_info */
|
||||
dp_tx_mon_free_ppdu_info(tx_ppdu_info);
|
||||
dp_tx_mon_free_ppdu_info(tx_ppdu_info, tx_mon_be);
|
||||
}
|
||||
qdf_spin_unlock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
qdf_spin_unlock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
|
||||
qdf_spinlock_destroy(&tx_cap_be->tx_mon_list_lock);
|
||||
qdf_spinlock_destroy(&tx_mon_be->tx_mon_list_lock);
|
||||
}
|
||||
#endif /* WLAN_TX_PKT_CAPTURE_ENH_BE */
|
||||
|
||||
#if (defined(WIFI_MONITOR_SUPPORT) && !defined(WLAN_TX_PKT_CAPTURE_ENH_BE))
|
||||
/*
|
||||
* dp_config_enh_tx_core_capture_2_0()- API to validate core framework
|
||||
* dp_config_enh_tx_core_monitor_2_0()- API to validate core framework
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
* @val: user provided value
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
dp_config_enh_tx_core_capture_2_0(struct dp_pdev *pdev, uint8_t val)
|
||||
dp_config_enh_tx_core_monitor_2_0(struct dp_pdev *pdev, uint8_t val)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be =
|
||||
dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be =
|
||||
&mon_pdev_be->tx_capture_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be =
|
||||
&mon_pdev_be->tx_monitor_be;
|
||||
|
||||
switch (val) {
|
||||
case TX_MON_BE_FRM_WRK_DISABLE:
|
||||
{
|
||||
tx_cap_be->mode = val;
|
||||
tx_mon_be->mode = val;
|
||||
mon_pdev_be->tx_mon_mode = 0;
|
||||
mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_64B;
|
||||
break;
|
||||
}
|
||||
case TX_MON_BE_FRM_WRK_FULL_CAPTURE:
|
||||
{
|
||||
tx_cap_be->mode = val;
|
||||
tx_mon_be->mode = val;
|
||||
mon_pdev_be->tx_mon_mode = 1;
|
||||
mon_pdev_be->tx_mon_filter_length = DEFAULT_DMA_LENGTH;
|
||||
break;
|
||||
}
|
||||
case TX_MON_BE_FRM_WRK_128B_CAPTURE:
|
||||
{
|
||||
tx_cap_be->mode = val;
|
||||
tx_mon_be->mode = val;
|
||||
mon_pdev_be->tx_mon_mode = 1;
|
||||
mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_128B;
|
||||
break;
|
||||
@@ -937,7 +864,7 @@ dp_config_enh_tx_core_capture_2_0(struct dp_pdev *pdev, uint8_t val)
|
||||
}
|
||||
|
||||
dp_mon_debug("Tx monitor mode:%d mon_mode_flag:%d config_length:%d",
|
||||
tx_cap_be->mode, mon_pdev_be->tx_mon_mode,
|
||||
tx_mon_be->mode, mon_pdev_be->tx_mon_mode,
|
||||
mon_pdev_be->tx_mon_filter_length);
|
||||
|
||||
/* send HTT msg to configure TLV based on mode */
|
||||
|
@@ -22,6 +22,19 @@
|
||||
#include <hal_be_api_mon.h>
|
||||
|
||||
struct dp_mon_desc;
|
||||
|
||||
/**
|
||||
* dp_tx_mon_desc_list - structure to store double linked liskt
|
||||
* @tx_ppdu_info_dlist_elem: support adding to double linked list
|
||||
* @tx_ppdu_info_slist_elem: support adding to single linked list
|
||||
* @tx_mon_reap_cnt: tx monitor reap count
|
||||
*/
|
||||
struct dp_tx_mon_desc_list {
|
||||
union dp_mon_desc_list_elem_t *desc_list;
|
||||
union dp_mon_desc_list_elem_t *tail;
|
||||
uint32_t tx_mon_reap_cnt;
|
||||
};
|
||||
|
||||
/*
|
||||
* dp_tx_mon_buffers_alloc() - allocate tx monitor buffers
|
||||
* @soc: DP soc handle
|
||||
@@ -87,6 +100,21 @@ dp_tx_mon_buf_desc_pool_alloc(struct dp_soc *soc);
|
||||
void dp_tx_mon_update_end_reason(struct dp_mon_pdev *mon_pdev,
|
||||
int ppdu_id, int end_reason);
|
||||
|
||||
/**
|
||||
* dp_tx_mon_status_free_packet_buf() - API to free packet buffer
|
||||
* @pdev: pdev Handle
|
||||
* @status_frag: status frag
|
||||
* @end_offset: status fragment end offset
|
||||
* @mon_desc_list_ref: tx monitor descriptor list reference
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void
|
||||
dp_tx_mon_status_free_packet_buf(struct dp_pdev *pdev,
|
||||
qdf_frag_t status_frag,
|
||||
uint32_t end_offset,
|
||||
struct dp_tx_mon_desc_list *mon_desc_list_ref);
|
||||
|
||||
/*
|
||||
* dp_tx_mon_process_status_tlv() - API to processed TLV
|
||||
* invoked from interrupt handler
|
||||
@@ -96,14 +124,17 @@ void dp_tx_mon_update_end_reason(struct dp_mon_pdev *mon_pdev,
|
||||
* @mon_ring_desc - descriptor status info
|
||||
* @addr - status buffer frag address
|
||||
* @end_offset - end offset of buffer that has valid buffer
|
||||
* @mon_desc_list_ref: tx monitor descriptor list reference
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_tx_mon_process_status_tlv(struct dp_soc *soc,
|
||||
QDF_STATUS
|
||||
dp_tx_mon_process_status_tlv(struct dp_soc *soc,
|
||||
struct dp_pdev *pdev,
|
||||
struct hal_mon_desc *mon_ring_desc,
|
||||
qdf_frag_t status_frag,
|
||||
uint32_t end_offset);
|
||||
uint32_t end_offset,
|
||||
struct dp_tx_mon_desc_list *mon_desc_list_ref);
|
||||
|
||||
/*
|
||||
* dp_tx_mon_process_2_0() - tx monitor interrupt process
|
||||
@@ -385,13 +416,15 @@ enum dp_tx_monitor_framework_mode {
|
||||
|
||||
#ifndef WLAN_TX_PKT_CAPTURE_ENH_BE
|
||||
/**
|
||||
* dp_pdev_tx_capture_be - info to store tx capture information in pdev
|
||||
* dp_pdev_tx_monitor_be - info to store tx capture information in pdev
|
||||
* @be_ppdu_id: current ppdu id
|
||||
* @mode: tx monitor core framework current mode
|
||||
*
|
||||
* This is a dummy structure
|
||||
* @tx_stats: tx monitor drop stats for that mac
|
||||
*/
|
||||
struct dp_pdev_tx_capture_be {
|
||||
struct dp_pdev_tx_monitor_be {
|
||||
uint32_t be_ppdu_id;
|
||||
uint32_t mode;
|
||||
struct dp_tx_monitor_drop_stats tx_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -414,7 +447,7 @@ struct dp_txmon_frag_vec {
|
||||
};
|
||||
|
||||
/**
|
||||
* dp_pdev_tx_capture_be - info to store tx capture information in pdev
|
||||
* dp_pdev_tx_monitor_be - info to store tx capture information in pdev
|
||||
* @be_ppdu_id: current ppdu id
|
||||
* @be_end_reason_bitmap: current end reason bitmap
|
||||
* @mode: tx monitor current mode
|
||||
@@ -436,7 +469,7 @@ struct dp_txmon_frag_vec {
|
||||
* @cur_frag_q_idx: current index of frag buffer
|
||||
* @status_frag_queue: array of status frag queue to hold 64 status buffer
|
||||
*/
|
||||
struct dp_pdev_tx_capture_be {
|
||||
struct dp_pdev_tx_monitor_be {
|
||||
uint32_t be_ppdu_id;
|
||||
uint32_t be_end_reason_bitmap;
|
||||
uint32_t mode;
|
||||
@@ -491,19 +524,23 @@ void dp_tx_mon_ppdu_info_free(struct dp_tx_ppdu_info *tx_ppdu_info);
|
||||
* dp_tx_mon_free_usr_mpduq() - API to free user mpduq
|
||||
* @tx_ppdu_info - pointer to tx_ppdu_info
|
||||
* @usr_idx - user index
|
||||
* @tx_cap_be - pointer to tx capture be
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void dp_tx_mon_free_usr_mpduq(struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
uint8_t usr_idx);
|
||||
uint8_t usr_idx,
|
||||
struct dp_pdev_tx_monitor_be *tx_cap_be);
|
||||
|
||||
/*
|
||||
* dp_tx_mon_free_ppdu_info() - API to free dp_tx_ppdu_info
|
||||
* @tx_ppdu_info - pointer to tx_ppdu_info
|
||||
* @tx_cap_be - pointer to tx capture be
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void dp_tx_mon_free_ppdu_info(struct dp_tx_ppdu_info *tx_ppdu_info);
|
||||
void dp_tx_mon_free_ppdu_info(struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
struct dp_pdev_tx_monitor_be *tx_cap_be);
|
||||
|
||||
/*
|
||||
* dp_tx_mon_get_ppdu_info() - API to allocate dp_tx_ppdu_info
|
||||
@@ -537,21 +574,21 @@ void dp_tx_ppdu_stats_attach_2_0(struct dp_pdev *pdev);
|
||||
void dp_tx_ppdu_stats_detach_2_0(struct dp_pdev *pdev);
|
||||
|
||||
/*
|
||||
* dp_print_pdev_tx_capture_stats_2_0: print tx capture stats
|
||||
* dp_print_pdev_tx_monitor_stats_2_0: print tx capture stats
|
||||
* @pdev: DP PDEV handle
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void dp_print_pdev_tx_capture_stats_2_0(struct dp_pdev *pdev);
|
||||
void dp_print_pdev_tx_monitor_stats_2_0(struct dp_pdev *pdev);
|
||||
|
||||
/*
|
||||
* dp_config_enh_tx_capture_be()- API to enable/disable enhanced tx capture
|
||||
* dp_config_enh_tx_monitor_2_0()- API to enable/disable enhanced tx capture
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
* @val: user provided value
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_config_enh_tx_capture_2_0(struct dp_pdev *pdev, uint8_t val);
|
||||
QDF_STATUS dp_config_enh_tx_monitor_2_0(struct dp_pdev *pdev, uint8_t val);
|
||||
|
||||
/*
|
||||
* dp_peer_set_tx_capture_enabled_2_0() - add tx monitor peer filter
|
||||
@@ -570,13 +607,13 @@ QDF_STATUS dp_peer_set_tx_capture_enabled_2_0(struct dp_pdev *pdev_handle,
|
||||
|
||||
#if (defined(WIFI_MONITOR_SUPPORT) && !defined(WLAN_TX_PKT_CAPTURE_ENH_BE))
|
||||
/*
|
||||
* dp_config_enh_tx_core_capture_2_0()- API to validate core framework
|
||||
* dp_config_enh_tx_core_monitor_2_0()- API to validate core framework
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
* @val: user provided value
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_config_enh_tx_core_capture_2_0(struct dp_pdev *pdev, uint8_t val);
|
||||
QDF_STATUS dp_config_enh_tx_core_monitor_2_0(struct dp_pdev *pdev, uint8_t val);
|
||||
#endif
|
||||
|
||||
#endif /* _DP_TX_MON_2_0_H_ */
|
||||
|
@@ -26,38 +26,126 @@
|
||||
#include <dp_mon_2.0.h>
|
||||
#include <dp_lite_mon.h>
|
||||
|
||||
/**
|
||||
* dp_tx_mon_status_free_packet_buf() - API to free packet buffer
|
||||
* @pdev: pdev Handle
|
||||
* @status_frag: status frag
|
||||
* @end_offset: status fragment end offset
|
||||
* @mon_desc_list_ref: tx monitor descriptor list reference
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void
|
||||
dp_tx_mon_status_free_packet_buf(struct dp_pdev *pdev,
|
||||
qdf_frag_t status_frag, uint32_t end_offset,
|
||||
struct dp_tx_mon_desc_list *mon_desc_list_ref)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_mon_packet_info packet_info = {0};
|
||||
uint8_t *tx_tlv;
|
||||
uint8_t *mon_buf_tx_tlv;
|
||||
uint8_t *tx_tlv_start;
|
||||
|
||||
if (qdf_unlikely(!pdev))
|
||||
return;
|
||||
|
||||
mon_pdev = pdev->monitor_pdev;
|
||||
if (qdf_unlikely(!mon_pdev))
|
||||
return;
|
||||
|
||||
mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_tlv = status_frag;
|
||||
tx_tlv_start = tx_tlv;
|
||||
/*
|
||||
* parse each status buffer and find packet buffer in it
|
||||
*/
|
||||
do {
|
||||
if (hal_txmon_is_mon_buf_addr_tlv(pdev->soc->hal_soc, tx_tlv)) {
|
||||
struct dp_mon_desc *mon_desc = NULL;
|
||||
qdf_frag_t packet_buffer = NULL;
|
||||
|
||||
mon_buf_tx_tlv = ((uint8_t *)tx_tlv +
|
||||
HAL_RX_TLV64_HDR_SIZE);
|
||||
hal_txmon_populate_packet_info(pdev->soc->hal_soc,
|
||||
mon_buf_tx_tlv,
|
||||
&packet_info);
|
||||
|
||||
mon_desc = (struct dp_mon_desc *)(uintptr_t)packet_info.sw_cookie;
|
||||
|
||||
qdf_assert_always(mon_desc);
|
||||
|
||||
if (mon_desc->magic != DP_MON_DESC_MAGIC)
|
||||
qdf_assert_always(0);
|
||||
|
||||
if (!mon_desc->unmapped) {
|
||||
qdf_mem_unmap_page(pdev->soc->osdev,
|
||||
(qdf_dma_addr_t)mon_desc->paddr,
|
||||
DP_MON_DATA_BUFFER_SIZE,
|
||||
QDF_DMA_FROM_DEVICE);
|
||||
mon_desc->unmapped = 1;
|
||||
}
|
||||
|
||||
packet_buffer = (qdf_frag_t)(mon_desc->buf_addr);
|
||||
mon_desc->buf_addr = NULL;
|
||||
|
||||
qdf_assert_always(packet_buffer);
|
||||
/* increment reap count */
|
||||
mon_desc_list_ref->tx_mon_reap_cnt++;
|
||||
|
||||
/* add the mon_desc to free list */
|
||||
dp_mon_add_to_free_desc_list(&mon_desc_list_ref->desc_list,
|
||||
&mon_desc_list_ref->tail,
|
||||
mon_desc);
|
||||
|
||||
/* free buffer, mapped to descriptor */
|
||||
qdf_frag_free(packet_buffer);
|
||||
}
|
||||
|
||||
/* need api definition for hal_tx_status_get_next_tlv */
|
||||
tx_tlv = hal_tx_status_get_next_tlv(tx_tlv);
|
||||
} while ((tx_tlv - tx_tlv_start) < end_offset);
|
||||
}
|
||||
|
||||
#if defined(WLAN_TX_PKT_CAPTURE_ENH_BE) && defined(QCA_MONITOR_2_0_SUPPORT)
|
||||
/**
|
||||
* dp_tx_mon_status_queue_free() - API to free status buffer
|
||||
* @pdev: pdev Handle
|
||||
* @tx_cap_be: pointer to tx_capture
|
||||
* @tx_mon_be: pointer to tx_monitor_be
|
||||
* @mon_desc_list_ref: tx monitor descriptor list reference
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void
|
||||
dp_tx_mon_status_queue_free(struct dp_pdev *pdev,
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be)
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be,
|
||||
struct dp_tx_mon_desc_list *mon_desc_list_ref)
|
||||
{
|
||||
uint8_t last_frag_q_idx = tx_cap_be->last_frag_q_idx;
|
||||
uint8_t last_frag_q_idx = tx_mon_be->last_frag_q_idx;
|
||||
qdf_frag_t status_frag = NULL;
|
||||
uint8_t i = tx_cap_be->cur_frag_q_idx;
|
||||
uint8_t i = tx_mon_be->cur_frag_q_idx;
|
||||
uint32_t end_offset = 0;
|
||||
|
||||
for (; i < last_frag_q_idx; i++) {
|
||||
status_frag = tx_cap_be->frag_q_vec[i].frag_buf;
|
||||
status_frag = tx_mon_be->frag_q_vec[i].frag_buf;
|
||||
|
||||
if (qdf_unlikely(!status_frag))
|
||||
continue;
|
||||
|
||||
end_offset = tx_cap_be->frag_q_vec[i].end_offset;
|
||||
hal_txmon_status_free_buffer(pdev->soc->hal_soc, status_frag,
|
||||
end_offset);
|
||||
end_offset = tx_mon_be->frag_q_vec[i].end_offset;
|
||||
dp_tx_mon_status_free_packet_buf(pdev, status_frag, end_offset,
|
||||
mon_desc_list_ref);
|
||||
qdf_frag_free(status_frag);
|
||||
tx_cap_be->frag_q_vec[i].frag_buf = NULL;
|
||||
tx_cap_be->frag_q_vec[i].end_offset = 0;
|
||||
tx_mon_be->frag_q_vec[i].frag_buf = NULL;
|
||||
tx_mon_be->frag_q_vec[i].end_offset = 0;
|
||||
}
|
||||
tx_cap_be->last_frag_q_idx = 0;
|
||||
tx_cap_be->cur_frag_q_idx = 0;
|
||||
tx_mon_be->last_frag_q_idx = 0;
|
||||
tx_mon_be->cur_frag_q_idx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,9 +157,11 @@ dp_tx_mon_status_queue_free(struct dp_pdev *pdev,
|
||||
* Return: void
|
||||
*/
|
||||
static void
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(struct dp_pdev *pdev,
|
||||
struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
uint8_t user_id, qdf_nbuf_t mpdu_nbuf)
|
||||
{
|
||||
qdf_nbuf_t radiotap = NULL;
|
||||
/* enqueue mpdu_nbuf to the per user mpdu_q */
|
||||
qdf_nbuf_queue_t *usr_mpdu_q = NULL;
|
||||
|
||||
@@ -81,7 +171,13 @@ dp_tx_mon_enqueue_mpdu_nbuf(struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
|
||||
usr_mpdu_q = &TXMON_PPDU_USR(tx_ppdu_info, user_id, mpdu_q);
|
||||
|
||||
qdf_nbuf_queue_add(usr_mpdu_q, mpdu_nbuf);
|
||||
radiotap = qdf_nbuf_alloc(pdev->soc->osdev, MAX_MONITOR_HEADER,
|
||||
MAX_MONITOR_HEADER,
|
||||
4, FALSE);
|
||||
|
||||
/* append ext list */
|
||||
qdf_nbuf_append_ext_list(radiotap, mpdu_nbuf, qdf_nbuf_len(mpdu_nbuf));
|
||||
qdf_nbuf_queue_add(usr_mpdu_q, radiotap);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -206,7 +302,7 @@ dp_tx_mon_generate_cts2self_frm(struct dp_pdev *pdev,
|
||||
/* enqueue 802.11 payload to per user mpdu_q */
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
uint16_t duration_le = 0;
|
||||
struct ieee80211_frame_min_one *wh_min = NULL;
|
||||
@@ -224,8 +320,8 @@ dp_tx_mon_generate_cts2self_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_status_info = &tx_cap_be->prot_status_info;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_status_info = &tx_mon_be->prot_status_info;
|
||||
|
||||
/*
|
||||
* for radiotap we allocate new skb,
|
||||
@@ -251,7 +347,7 @@ dp_tx_mon_generate_cts2self_frm(struct dp_pdev *pdev,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
qdf_nbuf_set_pktlen(mpdu_nbuf, sizeof(*wh_min));
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(tx_ppdu_info, 0, mpdu_nbuf);
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(pdev, tx_ppdu_info, 0, mpdu_nbuf);
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 1;
|
||||
}
|
||||
|
||||
@@ -270,7 +366,7 @@ dp_tx_mon_generate_rts_frm(struct dp_pdev *pdev,
|
||||
/* enqueue 802.11 payload to per user mpdu_q */
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
uint16_t duration_le = 0;
|
||||
struct ieee80211_ctlframe_addr2 *wh_min = NULL;
|
||||
@@ -288,8 +384,8 @@ dp_tx_mon_generate_rts_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_status_info = &tx_cap_be->prot_status_info;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_status_info = &tx_mon_be->prot_status_info;
|
||||
/*
|
||||
* for radiotap we allocate new skb,
|
||||
* so we don't need reserver skb header
|
||||
@@ -310,7 +406,7 @@ dp_tx_mon_generate_rts_frm(struct dp_pdev *pdev,
|
||||
wh_min->i_aidordur[0] = (duration_le & 0xFF);
|
||||
|
||||
if (!tx_status_info->protection_addr)
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
qdf_mem_copy(wh_min->i_addr1,
|
||||
TXMON_STATUS_INFO(tx_status_info, addr1),
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
@@ -319,7 +415,7 @@ dp_tx_mon_generate_rts_frm(struct dp_pdev *pdev,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
qdf_nbuf_set_pktlen(mpdu_nbuf, sizeof(*wh_min));
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(tx_ppdu_info, 0, mpdu_nbuf);
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(pdev, tx_ppdu_info, 0, mpdu_nbuf);
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 1;
|
||||
}
|
||||
|
||||
@@ -338,7 +434,7 @@ dp_tx_mon_generate_ack_frm(struct dp_pdev *pdev,
|
||||
/* enqueue 802.11 payload to per user mpdu_q */
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
struct ieee80211_frame_min_one *wh_addr1 = NULL;
|
||||
qdf_nbuf_t mpdu_nbuf = NULL;
|
||||
@@ -356,8 +452,8 @@ dp_tx_mon_generate_ack_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
/*
|
||||
* for radiotap we allocate new skb,
|
||||
* so we don't need reserver skb header
|
||||
@@ -379,7 +475,7 @@ dp_tx_mon_generate_ack_frm(struct dp_pdev *pdev,
|
||||
|
||||
qdf_nbuf_set_pktlen(mpdu_nbuf, sizeof(*wh_addr1));
|
||||
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(tx_ppdu_info, user_id, mpdu_nbuf);
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(pdev, tx_ppdu_info, user_id, mpdu_nbuf);
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 1;
|
||||
}
|
||||
|
||||
@@ -400,7 +496,7 @@ dp_tx_mon_generate_3addr_qos_null_frm(struct dp_pdev *pdev,
|
||||
/* enqueue 802.11 payload to per user mpdu_q */
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
struct ieee80211_qosframe *wh_addr3 = NULL;
|
||||
qdf_nbuf_t mpdu_nbuf = NULL;
|
||||
@@ -419,8 +515,8 @@ dp_tx_mon_generate_3addr_qos_null_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
/*
|
||||
* for radiotap we allocate new skb,
|
||||
* so we don't need reserver skb header
|
||||
@@ -453,7 +549,7 @@ dp_tx_mon_generate_3addr_qos_null_frm(struct dp_pdev *pdev,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
qdf_nbuf_set_pktlen(mpdu_nbuf, sizeof(*wh_addr3));
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(tx_ppdu_info, num_users, mpdu_nbuf);
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(pdev, tx_ppdu_info, num_users, mpdu_nbuf);
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 1;
|
||||
}
|
||||
|
||||
@@ -474,7 +570,7 @@ dp_tx_mon_generate_4addr_qos_null_frm(struct dp_pdev *pdev,
|
||||
/* enqueue 802.11 payload to per user mpdu_q */
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
struct ieee80211_qosframe_addr4 *wh_addr4 = NULL;
|
||||
qdf_nbuf_t mpdu_nbuf = NULL;
|
||||
@@ -493,8 +589,8 @@ dp_tx_mon_generate_4addr_qos_null_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
/*
|
||||
* for radiotap we allocate new skb,
|
||||
* so we don't need reserver skb header
|
||||
@@ -529,7 +625,7 @@ dp_tx_mon_generate_4addr_qos_null_frm(struct dp_pdev *pdev,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
qdf_nbuf_set_pktlen(mpdu_nbuf, sizeof(*wh_addr4));
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(tx_ppdu_info, num_users, mpdu_nbuf);
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(pdev, tx_ppdu_info, num_users, mpdu_nbuf);
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 1;
|
||||
}
|
||||
|
||||
@@ -558,7 +654,7 @@ dp_tx_mon_generate_mu_block_ack_frm(struct dp_pdev *pdev,
|
||||
/* enqueue 802.11 payload to per user mpdu_q */
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
struct ieee80211_ctlframe_addr2 *wh_addr2 = NULL;
|
||||
qdf_nbuf_t mpdu_nbuf = NULL;
|
||||
@@ -579,8 +675,8 @@ dp_tx_mon_generate_mu_block_ack_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
for (i = 0; i < num_users; i++)
|
||||
ba_sz += (4 << TXMON_BA_INFO_SZ(TXMON_PPDU_USR(tx_ppdu_info,
|
||||
i,
|
||||
@@ -647,7 +743,7 @@ dp_tx_mon_generate_mu_block_ack_frm(struct dp_pdev *pdev,
|
||||
(frm - (uint8_t *)qdf_nbuf_data(mpdu_nbuf)));
|
||||
|
||||
/* always enqueue to first active user */
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(tx_ppdu_info, 0, mpdu_nbuf);
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(pdev, tx_ppdu_info, 0, mpdu_nbuf);
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 1;
|
||||
}
|
||||
|
||||
@@ -666,7 +762,7 @@ dp_tx_mon_generate_block_ack_frm(struct dp_pdev *pdev,
|
||||
/* enqueue 802.11 payload to per user mpdu_q */
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
struct ieee80211_ctlframe_addr2 *wh_addr2 = NULL;
|
||||
qdf_nbuf_t mpdu_nbuf = NULL;
|
||||
@@ -687,8 +783,8 @@ dp_tx_mon_generate_block_ack_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
/*
|
||||
* for multi sta block ack, do we need to increase the size
|
||||
* or copy info on subsequent frame offset
|
||||
@@ -768,7 +864,7 @@ dp_tx_mon_generate_block_ack_frm(struct dp_pdev *pdev,
|
||||
qdf_nbuf_set_pktlen(mpdu_nbuf,
|
||||
(frm - (uint8_t *)qdf_nbuf_data(mpdu_nbuf)));
|
||||
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(tx_ppdu_info, 0, mpdu_nbuf);
|
||||
dp_tx_mon_enqueue_mpdu_nbuf(pdev, tx_ppdu_info, 0, mpdu_nbuf);
|
||||
|
||||
TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 1;
|
||||
}
|
||||
@@ -795,8 +891,7 @@ dp_tx_mon_alloc_mpdu(struct dp_pdev *pdev, struct dp_tx_ppdu_info *tx_ppdu_info)
|
||||
* we allocate a dummy bufffer size
|
||||
*/
|
||||
mpdu_nbuf = qdf_nbuf_alloc(pdev->soc->osdev,
|
||||
TXMON_NO_BUFFER_SZ,
|
||||
TXMON_NO_BUFFER_SZ,
|
||||
MAX_MONITOR_HEADER, MAX_MONITOR_HEADER,
|
||||
4, FALSE);
|
||||
if (!mpdu_nbuf) {
|
||||
qdf_err("%s: %d No memory to allocate mpdu_nbuf!!!!!\n",
|
||||
@@ -818,11 +913,12 @@ dp_tx_mon_alloc_mpdu(struct dp_pdev *pdev, struct dp_tx_ppdu_info *tx_ppdu_info)
|
||||
*/
|
||||
static void
|
||||
dp_tx_mon_generate_data_frm(struct dp_pdev *pdev,
|
||||
struct dp_tx_ppdu_info *tx_ppdu_info)
|
||||
struct dp_tx_ppdu_info *tx_ppdu_info,
|
||||
bool take_ref)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
qdf_nbuf_t mpdu_nbuf = NULL;
|
||||
qdf_nbuf_queue_t *usr_mpdu_q = NULL;
|
||||
@@ -840,9 +936,9 @@ dp_tx_mon_generate_data_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
usr_idx = TXMON_PPDU(tx_ppdu_info, cur_usr_idx);
|
||||
usr_mpdu_q = &TXMON_PPDU_USR(tx_ppdu_info, usr_idx, mpdu_q);
|
||||
mpdu_nbuf = qdf_nbuf_queue_last(usr_mpdu_q);
|
||||
@@ -856,8 +952,8 @@ dp_tx_mon_generate_data_frm(struct dp_pdev *pdev,
|
||||
mpdu_nbuf,
|
||||
TXMON_STATUS_INFO(tx_status_info, offset),
|
||||
TXMON_STATUS_INFO(tx_status_info, length),
|
||||
TX_MON_STATUS_BUF_SIZE,
|
||||
true, TXMON_NO_BUFFER_SZ);
|
||||
DP_MON_DATA_BUFFER_SIZE,
|
||||
take_ref, TXMON_NO_BUFFER_SZ);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -873,7 +969,7 @@ dp_tx_mon_generate_prot_frm(struct dp_pdev *pdev,
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
|
||||
/* sanity check */
|
||||
@@ -888,12 +984,12 @@ dp_tx_mon_generate_prot_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_status_info = &tx_cap_be->prot_status_info;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
tx_status_info = &tx_mon_be->prot_status_info;
|
||||
|
||||
/* update medium prot type from data */
|
||||
TXMON_STATUS_INFO(tx_status_info, medium_prot_type) =
|
||||
tx_cap_be->data_status_info.medium_prot_type;
|
||||
tx_mon_be->data_status_info.medium_prot_type;
|
||||
|
||||
switch (TXMON_STATUS_INFO(tx_status_info, medium_prot_type)) {
|
||||
case TXMON_MEDIUM_NO_PROTECTION:
|
||||
@@ -996,7 +1092,7 @@ dp_tx_mon_generated_response_frm(struct dp_pdev *pdev,
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
uint8_t gen_response = 0;
|
||||
@@ -1013,9 +1109,9 @@ dp_tx_mon_generated_response_frm(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
gen_response = TXMON_STATUS_INFO(tx_status_info, generated_response);
|
||||
|
||||
switch (gen_response) {
|
||||
@@ -1086,6 +1182,7 @@ dp_tx_mon_generated_response_frm(struct dp_pdev *pdev,
|
||||
* @tx_tlv_hdr: pointer to tx_tlv_hdr
|
||||
* @status_frag: pointer to fragment
|
||||
* @tlv_status: tlv status return from hal api
|
||||
* @mon_desc_list_ref: tx monitor descriptor list reference
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
@@ -1095,11 +1192,12 @@ dp_tx_mon_update_ppdu_info_status(struct dp_pdev *pdev,
|
||||
struct dp_tx_ppdu_info *tx_prot_ppdu_info,
|
||||
void *tx_tlv_hdr,
|
||||
qdf_frag_t status_frag,
|
||||
uint32_t tlv_status)
|
||||
uint32_t tlv_status,
|
||||
struct dp_tx_mon_desc_list *mon_desc_list_ref)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
@@ -1115,7 +1213,7 @@ dp_tx_mon_update_ppdu_info_status(struct dp_pdev *pdev,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
|
||||
switch (tlv_status) {
|
||||
case HAL_MON_TX_FES_SETUP:
|
||||
@@ -1136,7 +1234,7 @@ dp_tx_mon_update_ppdu_info_status(struct dp_pdev *pdev,
|
||||
* RTS(sta) - cts(AP)
|
||||
* BlockAckReq(sta) - BlockAck(AP)
|
||||
*/
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
if (TXMON_STATUS_INFO(tx_status_info, reception_type) ==
|
||||
TXMON_RESP_CTS)
|
||||
dp_tx_mon_generate_cts2self_frm(pdev,
|
||||
@@ -1177,9 +1275,9 @@ dp_tx_mon_update_ppdu_info_status(struct dp_pdev *pdev,
|
||||
* BlockAck is not same as ACK, single frame can hold
|
||||
* multiple BlockAck info
|
||||
*/
|
||||
tx_status_info = &tx_cap_be->data_status_info;
|
||||
if (TXMON_STATUS_INFO(tx_status_info, transmission_type) ==
|
||||
TXMON_SU_TRANSMISSION)
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
|
||||
if (TXMON_PPDU_HAL(tx_data_ppdu_info, num_users))
|
||||
dp_tx_mon_generate_block_ack_frm(pdev,
|
||||
tx_data_ppdu_info);
|
||||
else
|
||||
@@ -1199,10 +1297,56 @@ dp_tx_mon_update_ppdu_info_status(struct dp_pdev *pdev,
|
||||
break;
|
||||
}
|
||||
case HAL_MON_TX_DATA:
|
||||
case HAL_MON_TX_BUFFER_ADDR:
|
||||
{
|
||||
TXMON_PPDU_HAL(tx_data_ppdu_info, is_used) = 1;
|
||||
dp_tx_mon_generate_data_frm(pdev, tx_data_ppdu_info);
|
||||
dp_tx_mon_generate_data_frm(pdev, tx_data_ppdu_info, true);
|
||||
break;
|
||||
}
|
||||
case HAL_MON_TX_BUFFER_ADDR:
|
||||
{
|
||||
struct hal_mon_packet_info *packet_info = NULL;
|
||||
struct dp_mon_desc *mon_desc = NULL;
|
||||
qdf_frag_t packet_buffer = NULL;
|
||||
uint32_t end_offset = 0;
|
||||
|
||||
tx_status_info = &tx_mon_be->data_status_info;
|
||||
/* update buffer from packet info */
|
||||
packet_info = &TXMON_PPDU_HAL(tx_data_ppdu_info, packet_info);
|
||||
mon_desc = (struct dp_mon_desc *)(uintptr_t)packet_info->sw_cookie;
|
||||
|
||||
qdf_assert_always(mon_desc);
|
||||
|
||||
if (mon_desc->magic != DP_MON_DESC_MAGIC)
|
||||
qdf_assert_always(0);
|
||||
|
||||
qdf_assert_always(mon_desc->buf_addr);
|
||||
|
||||
if (!mon_desc->unmapped) {
|
||||
qdf_mem_unmap_page(pdev->soc->osdev,
|
||||
(qdf_dma_addr_t)mon_desc->paddr,
|
||||
DP_MON_DATA_BUFFER_SIZE,
|
||||
QDF_DMA_FROM_DEVICE);
|
||||
mon_desc->unmapped = 1;
|
||||
}
|
||||
|
||||
packet_buffer = mon_desc->buf_addr;
|
||||
mon_desc->buf_addr = NULL;
|
||||
|
||||
/* increment reap count */
|
||||
mon_desc_list_ref->tx_mon_reap_cnt++;
|
||||
|
||||
/* add the mon_desc to free list */
|
||||
dp_mon_add_to_free_desc_list(&mon_desc_list_ref->desc_list,
|
||||
&mon_desc_list_ref->tail,
|
||||
mon_desc);
|
||||
|
||||
TXMON_STATUS_INFO(tx_status_info, buffer) = packet_buffer;
|
||||
TXMON_STATUS_INFO(tx_status_info, offset) = end_offset;
|
||||
TXMON_STATUS_INFO(tx_status_info,
|
||||
length) = packet_info->dma_length;
|
||||
|
||||
TXMON_PPDU_HAL(tx_data_ppdu_info, is_used) = 1;
|
||||
dp_tx_mon_generate_data_frm(pdev, tx_data_ppdu_info, false);
|
||||
break;
|
||||
}
|
||||
case HAL_MON_TX_FES_STATUS_END:
|
||||
@@ -1240,26 +1384,30 @@ dp_tx_mon_update_ppdu_info_status(struct dp_pdev *pdev,
|
||||
/*
|
||||
* dp_tx_mon_process_tlv_2_0() - API to parse PPDU worth information
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
* @mon_desc_list_ref: tx monitor descriptor list reference
|
||||
*
|
||||
* Return: status
|
||||
*/
|
||||
QDF_STATUS dp_tx_mon_process_tlv_2_0(struct dp_pdev *pdev)
|
||||
QDF_STATUS
|
||||
dp_tx_mon_process_tlv_2_0(struct dp_pdev *pdev,
|
||||
struct dp_tx_mon_desc_list *mon_desc_list_ref)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
struct dp_tx_ppdu_info *tx_prot_ppdu_info = NULL;
|
||||
struct dp_tx_ppdu_info *tx_data_ppdu_info = NULL;
|
||||
struct hal_tx_status_info *tx_status_prot;
|
||||
struct hal_tx_status_info *tx_status_data;
|
||||
qdf_frag_t status_frag = NULL;
|
||||
uint32_t end_offset = 0;
|
||||
uint8_t *tx_tlv;
|
||||
uint8_t *tx_tlv_start;
|
||||
uint32_t tlv_status;
|
||||
uint32_t status = QDF_STATUS_SUCCESS;
|
||||
uint8_t num_users = 0;
|
||||
uint8_t cur_frag_q_idx;
|
||||
uint32_t end_offset = 0;
|
||||
bool schedule_wrq = false;
|
||||
|
||||
/* sanity check */
|
||||
if (qdf_unlikely(!pdev))
|
||||
@@ -1273,25 +1421,25 @@ QDF_STATUS dp_tx_mon_process_tlv_2_0(struct dp_pdev *pdev)
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
cur_frag_q_idx = tx_cap_be->cur_frag_q_idx;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
cur_frag_q_idx = tx_mon_be->cur_frag_q_idx;
|
||||
|
||||
tx_status_prot = &tx_cap_be->prot_status_info;
|
||||
tx_status_data = &tx_cap_be->data_status_info;
|
||||
tx_status_prot = &tx_mon_be->prot_status_info;
|
||||
tx_status_data = &tx_mon_be->data_status_info;
|
||||
|
||||
tx_prot_ppdu_info = dp_tx_mon_get_ppdu_info(pdev, TX_PROT_PPDU_INFO,
|
||||
1, tx_cap_be->be_ppdu_id);
|
||||
1, tx_mon_be->be_ppdu_id);
|
||||
|
||||
if (!tx_prot_ppdu_info) {
|
||||
dp_mon_info("tx prot ppdu info alloc got failed!!");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
status_frag = tx_cap_be->frag_q_vec[cur_frag_q_idx].frag_buf;
|
||||
end_offset = tx_cap_be->frag_q_vec[cur_frag_q_idx].end_offset;
|
||||
status_frag = tx_mon_be->frag_q_vec[cur_frag_q_idx].frag_buf;
|
||||
end_offset = tx_mon_be->frag_q_vec[cur_frag_q_idx].end_offset;
|
||||
tx_tlv = status_frag;
|
||||
dp_mon_debug("last_frag_q_idx: %d status_frag:%pK",
|
||||
tx_cap_be->last_frag_q_idx, status_frag);
|
||||
tx_mon_be->last_frag_q_idx, status_frag);
|
||||
|
||||
/* get number of user from tlv window */
|
||||
tlv_status = hal_txmon_status_get_num_users(pdev->soc->hal_soc,
|
||||
@@ -1305,18 +1453,18 @@ QDF_STATUS dp_tx_mon_process_tlv_2_0(struct dp_pdev *pdev)
|
||||
/* allocate tx_data_ppdu_info based on num_users */
|
||||
tx_data_ppdu_info = dp_tx_mon_get_ppdu_info(pdev, TX_DATA_PPDU_INFO,
|
||||
num_users,
|
||||
tx_cap_be->be_ppdu_id);
|
||||
tx_mon_be->be_ppdu_id);
|
||||
if (!tx_data_ppdu_info) {
|
||||
dp_mon_info("tx prot ppdu info alloc got failed!!");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
/* iterate status buffer queue */
|
||||
while (tx_cap_be->cur_frag_q_idx < tx_cap_be->last_frag_q_idx &&
|
||||
while (tx_mon_be->cur_frag_q_idx < tx_mon_be->last_frag_q_idx &&
|
||||
status == QDF_STATUS_SUCCESS) {
|
||||
/* get status buffer from frag_q_vec */
|
||||
status_frag = tx_cap_be->frag_q_vec[cur_frag_q_idx].frag_buf;
|
||||
end_offset = tx_cap_be->frag_q_vec[cur_frag_q_idx].end_offset;
|
||||
status_frag = tx_mon_be->frag_q_vec[cur_frag_q_idx].frag_buf;
|
||||
end_offset = tx_mon_be->frag_q_vec[cur_frag_q_idx].end_offset;
|
||||
if (qdf_unlikely(!status_frag)) {
|
||||
dp_mon_err("status frag is NULL\n");
|
||||
QDF_BUG(0);
|
||||
@@ -1344,12 +1492,14 @@ QDF_STATUS dp_tx_mon_process_tlv_2_0(struct dp_pdev *pdev)
|
||||
tx_prot_ppdu_info,
|
||||
tx_tlv,
|
||||
status_frag,
|
||||
tlv_status);
|
||||
tlv_status,
|
||||
mon_desc_list_ref);
|
||||
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
dp_tx_mon_status_free_packet_buf(pdev,
|
||||
status_frag,
|
||||
end_offset);
|
||||
end_offset,
|
||||
mon_desc_list_ref);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1364,13 +1514,13 @@ QDF_STATUS dp_tx_mon_process_tlv_2_0(struct dp_pdev *pdev)
|
||||
* is status_frag mapped to mpdu if so make sure
|
||||
*/
|
||||
qdf_frag_free(status_frag);
|
||||
tx_cap_be->frag_q_vec[cur_frag_q_idx].frag_buf = NULL;
|
||||
tx_cap_be->frag_q_vec[cur_frag_q_idx].end_offset = 0;
|
||||
cur_frag_q_idx = ++tx_cap_be->cur_frag_q_idx;
|
||||
tx_mon_be->frag_q_vec[cur_frag_q_idx].frag_buf = NULL;
|
||||
tx_mon_be->frag_q_vec[cur_frag_q_idx].end_offset = 0;
|
||||
cur_frag_q_idx = ++tx_mon_be->cur_frag_q_idx;
|
||||
}
|
||||
|
||||
/* clear the unreleased frag array */
|
||||
dp_tx_mon_status_queue_free(pdev, tx_cap_be);
|
||||
dp_tx_mon_status_queue_free(pdev, tx_mon_be, mon_desc_list_ref);
|
||||
|
||||
if (TXMON_PPDU_HAL(tx_prot_ppdu_info, is_used)) {
|
||||
if (qdf_unlikely(!TXMON_PPDU_COM(tx_prot_ppdu_info,
|
||||
@@ -1393,21 +1543,20 @@ QDF_STATUS dp_tx_mon_process_tlv_2_0(struct dp_pdev *pdev)
|
||||
*
|
||||
* TODO: add a threshold check and drop the ppdu info
|
||||
*/
|
||||
qdf_spin_lock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
tx_cap_be->last_prot_ppdu_info =
|
||||
tx_cap_be->tx_prot_ppdu_info;
|
||||
STAILQ_INSERT_TAIL(&tx_cap_be->tx_ppdu_info_queue,
|
||||
qdf_spin_lock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
tx_mon_be->last_prot_ppdu_info =
|
||||
tx_mon_be->tx_prot_ppdu_info;
|
||||
STAILQ_INSERT_TAIL(&tx_mon_be->tx_ppdu_info_queue,
|
||||
tx_prot_ppdu_info,
|
||||
tx_ppdu_info_queue_elem);
|
||||
tx_cap_be->tx_ppdu_info_list_depth++;
|
||||
tx_mon_be->tx_ppdu_info_list_depth++;
|
||||
|
||||
tx_cap_be->tx_prot_ppdu_info = NULL;
|
||||
qdf_spin_unlock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
tx_mon_be->tx_prot_ppdu_info = NULL;
|
||||
qdf_spin_unlock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
schedule_wrq = true;
|
||||
} else {
|
||||
/*
|
||||
* TODO : we can also save
|
||||
* allocated buffer for future use
|
||||
*/
|
||||
dp_tx_mon_free_ppdu_info(tx_prot_ppdu_info, tx_mon_be);
|
||||
tx_mon_be->tx_prot_ppdu_info = NULL;
|
||||
tx_prot_ppdu_info = NULL;
|
||||
}
|
||||
|
||||
@@ -1432,30 +1581,26 @@ QDF_STATUS dp_tx_mon_process_tlv_2_0(struct dp_pdev *pdev)
|
||||
*
|
||||
* TODO: add a threshold check and drop the ppdu info
|
||||
*/
|
||||
qdf_spin_lock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
tx_cap_be->last_data_ppdu_info =
|
||||
tx_cap_be->tx_data_ppdu_info;
|
||||
STAILQ_INSERT_TAIL(&tx_cap_be->tx_ppdu_info_queue,
|
||||
qdf_spin_lock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
tx_mon_be->last_data_ppdu_info =
|
||||
tx_mon_be->tx_data_ppdu_info;
|
||||
STAILQ_INSERT_TAIL(&tx_mon_be->tx_ppdu_info_queue,
|
||||
tx_data_ppdu_info,
|
||||
tx_ppdu_info_queue_elem);
|
||||
tx_cap_be->tx_ppdu_info_list_depth++;
|
||||
tx_mon_be->tx_ppdu_info_list_depth++;
|
||||
|
||||
tx_cap_be->tx_data_ppdu_info = NULL;
|
||||
qdf_spin_unlock_bh(&tx_cap_be->tx_mon_list_lock);
|
||||
tx_mon_be->tx_data_ppdu_info = NULL;
|
||||
qdf_spin_unlock_bh(&tx_mon_be->tx_mon_list_lock);
|
||||
schedule_wrq = true;
|
||||
} else {
|
||||
/*
|
||||
* TODO : we can also save
|
||||
* allocated buffer for future use
|
||||
*/
|
||||
dp_tx_mon_free_ppdu_info(tx_data_ppdu_info, tx_mon_be);
|
||||
tx_mon_be->tx_data_ppdu_info = NULL;
|
||||
tx_data_ppdu_info = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: iterate status buffer queue and free
|
||||
* need a wrapper function to free the status buffer
|
||||
*/
|
||||
qdf_queue_work(0, tx_cap_be->post_ppdu_workqueue,
|
||||
&tx_cap_be->post_ppdu_work);
|
||||
if (schedule_wrq)
|
||||
qdf_queue_work(NULL, tx_mon_be->post_ppdu_workqueue,
|
||||
&tx_mon_be->post_ppdu_work);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1473,18 +1618,15 @@ void dp_tx_mon_update_end_reason(struct dp_mon_pdev *mon_pdev,
|
||||
int ppdu_id, int end_reason)
|
||||
{
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
|
||||
mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
|
||||
if (tx_cap_be->be_ppdu_id != ppdu_id)
|
||||
return;
|
||||
|
||||
tx_cap_be->be_end_reason_bitmap |= (1 << end_reason);
|
||||
tx_mon_be->be_end_reason_bitmap |= (1 << end_reason);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1496,18 +1638,21 @@ void dp_tx_mon_update_end_reason(struct dp_mon_pdev *mon_pdev,
|
||||
* @mon_ring_desc - descriptor status info
|
||||
* @addr - status buffer frag address
|
||||
* @end_offset - end offset of buffer that has valid buffer
|
||||
* @mon_desc_list_ref: tx monitor descriptor list reference
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_tx_mon_process_status_tlv(struct dp_soc *soc,
|
||||
QDF_STATUS
|
||||
dp_tx_mon_process_status_tlv(struct dp_soc *soc,
|
||||
struct dp_pdev *pdev,
|
||||
struct hal_mon_desc *mon_ring_desc,
|
||||
qdf_frag_t status_frag,
|
||||
uint32_t end_offset)
|
||||
uint32_t end_offset,
|
||||
struct dp_tx_mon_desc_list *mon_desc_list_ref)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_capture_be *tx_cap_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
uint8_t last_frag_q_idx = 0;
|
||||
|
||||
/* sanity check */
|
||||
@@ -1522,63 +1667,72 @@ QDF_STATUS dp_tx_mon_process_status_tlv(struct dp_soc *soc,
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
goto free_status_buffer;
|
||||
|
||||
tx_cap_be = &mon_pdev_be->tx_capture_be;
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
|
||||
if (qdf_unlikely(tx_cap_be->last_frag_q_idx >
|
||||
if (qdf_unlikely(tx_mon_be->last_frag_q_idx >
|
||||
MAX_STATUS_BUFFER_IN_PPDU)) {
|
||||
dp_mon_err("status frag queue for a ppdu[%d] exceed %d\n",
|
||||
tx_cap_be->be_ppdu_id,
|
||||
tx_mon_be->be_ppdu_id,
|
||||
MAX_STATUS_BUFFER_IN_PPDU);
|
||||
dp_tx_mon_status_queue_free(pdev, tx_cap_be);
|
||||
dp_tx_mon_status_queue_free(pdev, tx_mon_be, mon_desc_list_ref);
|
||||
goto free_status_buffer;
|
||||
}
|
||||
|
||||
if (tx_cap_be->mode == TX_MON_BE_DISABLE &&
|
||||
!dp_lite_mon_is_tx_enabled(mon_pdev))
|
||||
if (tx_mon_be->mode == TX_MON_BE_DISABLE &&
|
||||
!dp_lite_mon_is_tx_enabled(mon_pdev)) {
|
||||
dp_tx_mon_status_queue_free(pdev, tx_mon_be,
|
||||
mon_desc_list_ref);
|
||||
goto free_status_buffer;
|
||||
}
|
||||
|
||||
if (tx_cap_be->be_ppdu_id != mon_ring_desc->ppdu_id &&
|
||||
tx_cap_be->last_frag_q_idx) {
|
||||
if (tx_cap_be->be_end_reason_bitmap &
|
||||
if (tx_mon_be->be_ppdu_id != mon_ring_desc->ppdu_id &&
|
||||
tx_mon_be->last_frag_q_idx) {
|
||||
if (tx_mon_be->be_end_reason_bitmap &
|
||||
(1 << HAL_MON_FLUSH_DETECTED)) {
|
||||
dp_tx_mon_status_queue_free(pdev, tx_cap_be);
|
||||
} else if (tx_cap_be->be_end_reason_bitmap &
|
||||
dp_tx_mon_status_queue_free(pdev, tx_mon_be,
|
||||
mon_desc_list_ref);
|
||||
} else if (tx_mon_be->be_end_reason_bitmap &
|
||||
(1 << HAL_MON_PPDU_TRUNCATED)) {
|
||||
dp_tx_mon_status_queue_free(pdev, tx_cap_be);
|
||||
dp_tx_mon_status_queue_free(pdev, tx_mon_be,
|
||||
mon_desc_list_ref);
|
||||
} else {
|
||||
dp_mon_err("End of ppdu not seen PID:%d cur_pid:%d idx:%d",
|
||||
tx_cap_be->be_ppdu_id,
|
||||
tx_mon_be->be_ppdu_id,
|
||||
mon_ring_desc->ppdu_id,
|
||||
tx_cap_be->last_frag_q_idx);
|
||||
tx_mon_be->last_frag_q_idx);
|
||||
/* schedule ppdu worth information */
|
||||
dp_tx_mon_status_queue_free(pdev, tx_cap_be);
|
||||
dp_tx_mon_status_queue_free(pdev, tx_mon_be,
|
||||
mon_desc_list_ref);
|
||||
}
|
||||
|
||||
/* reset end reason bitmap */
|
||||
tx_cap_be->be_end_reason_bitmap = 0;
|
||||
tx_cap_be->last_frag_q_idx = 0;
|
||||
tx_cap_be->cur_frag_q_idx = 0;
|
||||
tx_mon_be->be_end_reason_bitmap = 0;
|
||||
tx_mon_be->last_frag_q_idx = 0;
|
||||
tx_mon_be->cur_frag_q_idx = 0;
|
||||
}
|
||||
|
||||
tx_cap_be->be_ppdu_id = mon_ring_desc->ppdu_id;
|
||||
tx_cap_be->be_end_reason_bitmap |= (1 << mon_ring_desc->end_reason);
|
||||
tx_mon_be->be_ppdu_id = mon_ring_desc->ppdu_id;
|
||||
tx_mon_be->be_end_reason_bitmap |= (1 << mon_ring_desc->end_reason);
|
||||
|
||||
last_frag_q_idx = tx_cap_be->last_frag_q_idx;
|
||||
last_frag_q_idx = tx_mon_be->last_frag_q_idx;
|
||||
|
||||
tx_cap_be->frag_q_vec[last_frag_q_idx].frag_buf = status_frag;
|
||||
tx_cap_be->frag_q_vec[last_frag_q_idx].end_offset = end_offset;
|
||||
tx_cap_be->last_frag_q_idx++;
|
||||
tx_mon_be->frag_q_vec[last_frag_q_idx].frag_buf = status_frag;
|
||||
tx_mon_be->frag_q_vec[last_frag_q_idx].end_offset = end_offset;
|
||||
tx_mon_be->last_frag_q_idx++;
|
||||
|
||||
if (mon_ring_desc->end_reason == HAL_MON_END_OF_PPDU) {
|
||||
if (dp_tx_mon_process_tlv_2_0(pdev) != QDF_STATUS_SUCCESS)
|
||||
dp_tx_mon_status_queue_free(pdev, tx_cap_be);
|
||||
if (dp_tx_mon_process_tlv_2_0(pdev,
|
||||
mon_desc_list_ref) !=
|
||||
QDF_STATUS_SUCCESS)
|
||||
dp_tx_mon_status_queue_free(pdev, tx_mon_be,
|
||||
mon_desc_list_ref);
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
free_status_buffer:
|
||||
hal_txmon_status_free_buffer(pdev->soc->hal_soc,
|
||||
status_frag, end_offset);
|
||||
dp_tx_mon_status_free_packet_buf(pdev, status_frag, end_offset,
|
||||
mon_desc_list_ref);
|
||||
qdf_frag_free(status_frag);
|
||||
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
@@ -1595,17 +1749,38 @@ free_status_buffer:
|
||||
* @mon_ring_desc - descriptor status info
|
||||
* @addr - status buffer frag address
|
||||
* @end_offset - end offset of buffer that has valid buffer
|
||||
* @mon_desc_list_ref: tx monitor descriptor list reference
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_tx_mon_process_status_tlv(struct dp_soc *soc,
|
||||
QDF_STATUS
|
||||
dp_tx_mon_process_status_tlv(struct dp_soc *soc,
|
||||
struct dp_pdev *pdev,
|
||||
struct hal_mon_desc *mon_ring_desc,
|
||||
qdf_frag_t status_frag,
|
||||
uint32_t end_offset)
|
||||
uint32_t end_offset,
|
||||
struct dp_tx_mon_desc_list *mon_desc_list_ref)
|
||||
{
|
||||
hal_txmon_status_free_buffer(pdev->soc->hal_soc,
|
||||
status_frag, end_offset);
|
||||
struct dp_mon_pdev *mon_pdev;
|
||||
struct dp_mon_pdev_be *mon_pdev_be;
|
||||
struct dp_pdev_tx_monitor_be *tx_mon_be;
|
||||
|
||||
/* sanity check */
|
||||
if (qdf_unlikely(!pdev))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
mon_pdev = pdev->monitor_pdev;
|
||||
if (qdf_unlikely(!mon_pdev))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
|
||||
if (qdf_unlikely(!mon_pdev_be))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
tx_mon_be = &mon_pdev_be->tx_monitor_be;
|
||||
|
||||
dp_tx_mon_status_free_packet_buf(pdev, status_frag, end_offset,
|
||||
mon_desc_list_ref);
|
||||
qdf_frag_free(status_frag);
|
||||
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
@@ -57,6 +57,10 @@
|
||||
#define dp_mon_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_MON, params)
|
||||
#define dp_mon_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_MON, params)
|
||||
|
||||
#define dp_mon_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_MON, params)
|
||||
#define dp_mon_info_rl(params...) \
|
||||
__QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO_HIGH, QDF_MODULE_ID_MON, ## params)
|
||||
|
||||
#ifdef QCA_ENHANCED_STATS_SUPPORT
|
||||
typedef struct dp_peer_extd_tx_stats dp_mon_peer_tx_stats;
|
||||
typedef struct dp_peer_extd_rx_stats dp_mon_peer_rx_stats;
|
||||
|
@@ -866,6 +866,7 @@ struct hal_tx_status_info {
|
||||
* @cur_usr_idx: Current user index of the PPDU
|
||||
* @reserved: for furture purpose
|
||||
* @prot_tlv_status: protection tlv status
|
||||
* @packet_info: packet information
|
||||
* @rx_status: monitor mode rx status information
|
||||
* @rx_user_status: monitor mode rx user status information
|
||||
*/
|
||||
@@ -879,6 +880,8 @@ struct hal_tx_ppdu_info {
|
||||
|
||||
uint32_t prot_tlv_status;
|
||||
|
||||
/* placeholder to hold packet buffer info */
|
||||
struct hal_mon_packet_info packet_info;
|
||||
struct mon_rx_status rx_status;
|
||||
struct mon_rx_user_status rx_user_status[];
|
||||
};
|
||||
@@ -950,25 +953,6 @@ hal_txmon_status_get_num_users(hal_soc_handle_t hal_soc_hdl,
|
||||
num_users);
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_txmon_status_free_buffer() - api to free status buffer
|
||||
* @hal_soc: HAL soc handle
|
||||
* @status_frag: qdf_frag_t buffer
|
||||
* @end_offset: end offset within buffer that has valid data
|
||||
*
|
||||
* Return status
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
hal_txmon_status_free_buffer(hal_soc_handle_t hal_soc_hdl,
|
||||
qdf_frag_t status_frag,
|
||||
uint32_t end_offset)
|
||||
{
|
||||
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
||||
|
||||
return hal_soc->ops->hal_txmon_status_free_buffer(status_frag,
|
||||
end_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_tx_status_get_tlv_tag() - api to get tlv tag
|
||||
* @tx_tlv_hdr: pointer to TLV header
|
||||
@@ -986,6 +970,45 @@ hal_tx_status_get_tlv_tag(void *tx_tlv_hdr)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hal_txmon_is_mon_buf_addr_tlv() - api to find packet buffer addr tlv
|
||||
* @hal_soc: HAL soc handle
|
||||
* @tx_tlv_hdr: pointer to TLV header
|
||||
*
|
||||
* Return: bool
|
||||
*/
|
||||
static inline bool
|
||||
hal_txmon_is_mon_buf_addr_tlv(hal_soc_handle_t hal_soc_hdl, void *tx_tlv_hdr)
|
||||
{
|
||||
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
||||
|
||||
if (qdf_unlikely(!hal_soc->ops->hal_txmon_is_mon_buf_addr_tlv))
|
||||
return false;
|
||||
|
||||
return hal_soc->ops->hal_txmon_is_mon_buf_addr_tlv(tx_tlv_hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_txmon_populate_packet_info() - api to populate packet info
|
||||
* @hal_soc: HAL soc handle
|
||||
* @tx_tlv_hdr: pointer to TLV header
|
||||
* @packet_info: pointer to placeholder for packet info
|
||||
*
|
||||
* Return void
|
||||
*/
|
||||
static inline void
|
||||
hal_txmon_populate_packet_info(hal_soc_handle_t hal_soc_hdl,
|
||||
void *tx_tlv_hdr,
|
||||
void *packet_info)
|
||||
{
|
||||
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
||||
|
||||
if (qdf_unlikely(!hal_soc->ops->hal_txmon_populate_packet_info))
|
||||
return;
|
||||
|
||||
hal_soc->ops->hal_txmon_populate_packet_info(tx_tlv_hdr, packet_info);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
hal_rx_parse_u_sig_cmn(struct hal_soc *hal_soc, void *rx_tlv,
|
||||
struct hal_rx_ppdu_info *ppdu_info)
|
||||
|
@@ -326,34 +326,43 @@ hal_rx_fst_get_fse_size_be(void)
|
||||
|
||||
#ifdef QCA_MONITOR_2_0_SUPPORT
|
||||
/**
|
||||
* hal_txmon_get_buffer_addr_generic_be() - api to get buffer address
|
||||
* hal_txmon_is_mon_buf_addr_tlv_generic_be() - api to find mon buffer tlv
|
||||
* @tx_tlv: pointer to TLV header
|
||||
* @status: hal mon buffer address status
|
||||
*
|
||||
* Return: Address to qdf_frag_t
|
||||
* Return: bool based on tlv tag matches monitor buffer address tlv
|
||||
*/
|
||||
static inline qdf_frag_t
|
||||
hal_txmon_get_buffer_addr_generic_be(void *tx_tlv,
|
||||
struct hal_mon_buf_addr_status *status)
|
||||
static inline bool
|
||||
hal_txmon_is_mon_buf_addr_tlv_generic_be(void *tx_tlv_hdr)
|
||||
{
|
||||
struct mon_buffer_addr *hal_buffer_addr =
|
||||
(struct mon_buffer_addr *)((uint8_t *)tx_tlv +
|
||||
HAL_RX_TLV64_HDR_SIZE);
|
||||
qdf_frag_t buf_addr = NULL;
|
||||
uint32_t tlv_tag;
|
||||
|
||||
buf_addr = (qdf_frag_t)(uintptr_t)((hal_buffer_addr->buffer_virt_addr_31_0 |
|
||||
((unsigned long long)hal_buffer_addr->buffer_virt_addr_63_32 <<
|
||||
32)));
|
||||
tlv_tag = HAL_RX_GET_USER_TLV64_TYPE(tx_tlv_hdr);
|
||||
|
||||
/* qdf_frag_t is derived from buffer address tlv */
|
||||
if (qdf_unlikely(status)) {
|
||||
qdf_mem_copy(status,
|
||||
(uint8_t *)tx_tlv + HAL_RX_TLV64_HDR_SIZE,
|
||||
sizeof(struct hal_mon_buf_addr_status));
|
||||
/* update hal_mon_buf_addr_status */
|
||||
}
|
||||
if (WIFIMON_BUFFER_ADDR_E == tlv_tag)
|
||||
return true;
|
||||
|
||||
return buf_addr;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_txmon_populate_packet_info_generic_be() - api to populate packet info
|
||||
* @tx_tlv: pointer to TLV header
|
||||
* @packet_info: place holder for packet info
|
||||
*
|
||||
* Return: Address to void
|
||||
*/
|
||||
static inline void
|
||||
hal_txmon_populate_packet_info_generic_be(void *tx_tlv, void *packet_info)
|
||||
{
|
||||
struct hal_mon_packet_info *pkt_info;
|
||||
struct mon_buffer_addr *addr = (struct mon_buffer_addr *)tx_tlv;
|
||||
|
||||
pkt_info = (struct hal_mon_packet_info *)packet_info;
|
||||
pkt_info->sw_cookie = (((uint64_t)addr->buffer_virt_addr_63_32 << 32) |
|
||||
(addr->buffer_virt_addr_31_0));
|
||||
pkt_info->dma_length = addr->dma_length + 1;
|
||||
pkt_info->msdu_continuation = addr->msdu_continuation;
|
||||
pkt_info->truncated = addr->truncated;
|
||||
}
|
||||
|
||||
#if defined(TX_MONITOR_WORD_MASK)
|
||||
@@ -657,60 +666,6 @@ hal_txmon_status_get_num_users_generic_be(void *tx_tlv_hdr, uint8_t *num_users)
|
||||
return tlv_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_txmon_free_status_buffer() - api to free status buffer
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
* @status_frag: qdf_frag_t buffer
|
||||
* @end_offset: end offset within buffer that has valid data
|
||||
*
|
||||
* Return status
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
hal_txmon_status_free_buffer_generic_be(qdf_frag_t status_frag,
|
||||
uint32_t end_offset)
|
||||
{
|
||||
uint32_t tlv_tag, tlv_len;
|
||||
uint32_t tlv_status = HAL_MON_TX_STATUS_PPDU_NOT_DONE;
|
||||
uint8_t *tx_tlv;
|
||||
uint8_t *tx_tlv_start;
|
||||
qdf_frag_t frag_buf = NULL;
|
||||
QDF_STATUS status = QDF_STATUS_E_ABORTED;
|
||||
|
||||
tx_tlv = (uint8_t *)status_frag;
|
||||
tx_tlv_start = tx_tlv;
|
||||
/* parse tlv and populate tx_ppdu_info */
|
||||
do {
|
||||
tlv_tag = HAL_RX_GET_USER_TLV64_TYPE(tx_tlv);
|
||||
tlv_len = HAL_RX_GET_USER_TLV64_LEN(tx_tlv);
|
||||
|
||||
if (((tx_tlv - tx_tlv_start) + tlv_len) > end_offset)
|
||||
return QDF_STATUS_E_ABORTED;
|
||||
|
||||
if (tlv_tag == WIFIMON_BUFFER_ADDR_E) {
|
||||
frag_buf = hal_txmon_get_buffer_addr_generic_be(tx_tlv,
|
||||
NULL);
|
||||
if (frag_buf)
|
||||
qdf_frag_free(frag_buf);
|
||||
|
||||
frag_buf = NULL;
|
||||
}
|
||||
|
||||
if (WIFITX_FES_STATUS_END_E == tlv_tag ||
|
||||
WIFIRESPONSE_END_STATUS_E == tlv_tag ||
|
||||
WIFIDUMMY_E == tlv_tag) {
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* need api definition for hal_tx_status_get_next_tlv */
|
||||
tx_tlv = hal_tx_status_get_next_tlv(tx_tlv);
|
||||
if ((tx_tlv - tx_tlv_start) >= end_offset)
|
||||
break;
|
||||
} while (tlv_status == HAL_MON_TX_STATUS_PPDU_NOT_DONE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_tx_get_ppdu_info() - api to get tx ppdu info
|
||||
* @pdev_handle: DP_PDEV handle
|
||||
@@ -794,8 +749,8 @@ hal_txmon_status_parse_tlv_generic_be(void *data_ppdu_info,
|
||||
{
|
||||
struct hal_tx_ppdu_info *ppdu_info;
|
||||
struct hal_tx_status_info *tx_status_info;
|
||||
struct hal_mon_packet_info *packet_info = NULL;
|
||||
uint32_t tlv_tag, user_id, tlv_len;
|
||||
qdf_frag_t frag_buf = NULL;
|
||||
uint32_t status = HAL_MON_TX_STATUS_PPDU_NOT_DONE;
|
||||
void *tx_tlv;
|
||||
|
||||
@@ -1043,21 +998,15 @@ hal_txmon_status_parse_tlv_generic_be(void *data_ppdu_info,
|
||||
}
|
||||
case WIFIMON_BUFFER_ADDR_E:/* DOWNSTREAM */
|
||||
{
|
||||
struct hal_mon_buf_addr_status buf_status = {0};
|
||||
|
||||
packet_info = &ppdu_info->packet_info;
|
||||
status = HAL_MON_TX_BUFFER_ADDR;
|
||||
/*
|
||||
* TODO: do we need a conversion api to convert
|
||||
* user_id from hw to get host user_index
|
||||
*/
|
||||
TXMON_HAL(ppdu_info, cur_usr_idx) = user_id;
|
||||
frag_buf = hal_txmon_get_buffer_addr_generic_be(tx_tlv,
|
||||
&buf_status);
|
||||
TXMON_STATUS_INFO(tx_status_info,
|
||||
buffer) = (void *)frag_buf;
|
||||
TXMON_STATUS_INFO(tx_status_info, offset) = 0;
|
||||
TXMON_STATUS_INFO(tx_status_info,
|
||||
length) = buf_status.dma_length;
|
||||
|
||||
hal_txmon_populate_packet_info_generic_be(tx_tlv, packet_info);
|
||||
|
||||
SHOW_DEFINED(WIFIMON_BUFFER_ADDR_E);
|
||||
break;
|
||||
@@ -1591,8 +1540,7 @@ hal_txmon_status_parse_tlv_generic_be(void *data_ppdu_info,
|
||||
BA_TS_CTRL);
|
||||
/* memcpy ba bitmap */
|
||||
qdf_mem_copy(TXMON_HAL_USER(ppdu_info, user_id, ba_bitmap),
|
||||
tx_tlv +
|
||||
HAL_TX_DESC_OFFSET_GET_64(tx_tlv,
|
||||
&HAL_SET_FLD_OFFSET_64(tx_tlv,
|
||||
RX_FRAME_1K_BITMAP_ACK,
|
||||
BA_TS_BITMAP_31_0, 0),
|
||||
4 << TXMON_HAL_USER(ppdu_info,
|
||||
|
@@ -1139,6 +1139,9 @@ struct hal_hw_txrx_ops {
|
||||
uint8_t (*hal_get_tlv_hdr_size)(void);
|
||||
uint8_t (*hal_get_idle_link_bm_id)(uint8_t chip_id);
|
||||
|
||||
bool (*hal_txmon_is_mon_buf_addr_tlv)(void *tx_tlv_hdr);
|
||||
void (*hal_txmon_populate_packet_info)(void *tx_tlv_hdr,
|
||||
void *pkt_info);
|
||||
/* TX MONITOR */
|
||||
#ifdef QCA_MONITOR_2_0_SUPPORT
|
||||
uint32_t (*hal_txmon_status_parse_tlv)(void *data_ppdu_info,
|
||||
@@ -1149,8 +1152,6 @@ struct hal_hw_txrx_ops {
|
||||
qdf_frag_t status_frag);
|
||||
uint32_t (*hal_txmon_status_get_num_users)(void *tx_tlv_hdr,
|
||||
uint8_t *num_users);
|
||||
QDF_STATUS (*hal_txmon_status_free_buffer)(qdf_frag_t status_frag,
|
||||
uint32_t end_offset);
|
||||
#endif /* QCA_MONITOR_2_0_SUPPORT */
|
||||
void (*hal_reo_shared_qaddr_setup)(hal_soc_handle_t hal_soc_hdl);
|
||||
void (*hal_reo_shared_qaddr_init)(hal_soc_handle_t hal_soc_hdl);
|
||||
|
@@ -1959,12 +1959,14 @@ static void hal_hw_txrx_ops_attach_qcn9224(struct hal_soc *hal_soc)
|
||||
hal_soc->ops->hal_get_reo_qdesc_size = hal_qcn9224_get_reo_qdesc_size;
|
||||
/* TX MONITOR */
|
||||
#ifdef QCA_MONITOR_2_0_SUPPORT
|
||||
hal_soc->ops->hal_txmon_is_mon_buf_addr_tlv =
|
||||
hal_txmon_is_mon_buf_addr_tlv_generic_be;
|
||||
hal_soc->ops->hal_txmon_populate_packet_info =
|
||||
hal_txmon_populate_packet_info_generic_be;
|
||||
hal_soc->ops->hal_txmon_status_parse_tlv =
|
||||
hal_txmon_status_parse_tlv_generic_be;
|
||||
hal_soc->ops->hal_txmon_status_get_num_users =
|
||||
hal_txmon_status_get_num_users_generic_be;
|
||||
hal_soc->ops->hal_txmon_status_free_buffer =
|
||||
hal_txmon_status_free_buffer_generic_be;
|
||||
#endif /* QCA_MONITOR_2_0_SUPPORT */
|
||||
hal_soc->ops->hal_compute_reo_remap_ix0 = NULL;
|
||||
hal_soc->ops->hal_tx_vdev_mismatch_routing_set =
|
||||
|
Reference in New Issue
Block a user