qcacmn: Monitor vdev and peer attach/detach

PATCH[5/7]:
This patch consists following changes:
 -Monitor vdev context allocation while vdev attach and free
  while vdev delete
 -Monitor peer context allocation while peer create and free while
  peer delete
 -Move monitor vdev timer function to monitor file
 -Move monitor reap timer handler function to monitor file
 -Move monitor timer related variables to monitor file
 -Add timer init/deinit and start/stop in monitor file.

Change-Id: I9c7910671d3678c53ca9ec44a57bc10e892008d9
CRs-Fixed: 2983994
This commit is contained in:
aloksing
2021-05-25 22:49:19 +05:30
committed by Madan Koyyalamudi
parent e7cc727374
commit c4796962ca
9 changed files with 798 additions and 287 deletions

View File

@@ -454,20 +454,6 @@ struct htt_stats_context {
uint32_t msg_len;
};
int
dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap);
/**
* dp_ppdu_desc_user_stats_update(): Function to update TX user stats
* @pdev: DP pdev handle
* @ppdu_info: per PPDU TLV descriptor
*
* return: void
*/
void
dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
struct ppdu_info *ppdu_info);
/**
* dp_htt_rx_flow_fst_setup(): Send HTT Rx FST setup message to FW
* @pdev: DP pdev handle

View File

@@ -192,6 +192,28 @@ static inline QDF_STATUS monitor_pdev_detach(struct dp_pdev *pdev)
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS monitor_vdev_attach(struct dp_vdev *vdev)
{
return QDF_STATUS_E_FAILURE;
}
static inline QDF_STATUS monitor_vdev_detach(struct dp_vdev *vdev)
{
return QDF_STATUS_E_FAILURE;
}
static inline QDF_STATUS monitor_peer_attach(struct dp_soc *soc,
struct dp_peer *peer)
{
return QDF_STATUS_E_FAILURE;
}
static inline QDF_STATUS monitor_peer_detach(struct dp_soc *soc,
struct dp_peer *peer)
{
return QDF_STATUS_E_FAILURE;
}
static inline QDF_STATUS monitor_pdev_init(struct dp_pdev *pdev)
{
return QDF_STATUS_SUCCESS;
@@ -387,6 +409,48 @@ static inline QDF_STATUS monitor_filter_neighbour_peer(struct dp_pdev *pdev,
static inline void monitor_print_pdev_tx_capture_stats(struct dp_pdev *pdev)
{
}
static inline
void monitor_reap_timer_init(struct dp_soc *soc)
{
}
static inline
void monitor_reap_timer_deinit(struct dp_soc *soc)
{
}
static inline
void monitor_reap_timer_start(struct dp_soc *soc)
{
}
static inline
bool monitor_reap_timer_stop(struct dp_soc *soc)
{
return false;
}
static inline
void monitor_vdev_timer_init(struct dp_soc *soc)
{
}
static inline
void monitor_vdev_timer_deinit(struct dp_soc *soc)
{
}
static inline
void monitor_vdev_timer_start(struct dp_soc *soc)
{
}
static inline
bool monitor_vdev_timer_stop(struct dp_soc *soc)
{
return false;
}
#endif
#ifndef WIFI_MONITOR_SUPPORT
@@ -400,6 +464,24 @@ static inline bool dp_is_enable_reap_timer_non_pkt(struct dp_pdev *pdev)
{
return false;
}
static inline void monitor_vdev_register_osif(struct dp_vdev *vdev,
struct ol_txrx_ops *txrx_ops)
{
}
static inline bool monitor_is_vdev_timer_running(struct dp_soc *soc)
{
return false;
}
static inline void monitor_vdev_delete(struct dp_soc *soc, struct dp_vdev *vdev)
{
}
static inline void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
{
}
#endif
#define DP_MAX_TIMER_EXEC_TIME_TICKS \
@@ -1300,13 +1382,6 @@ void dp_peer_find_id_to_obj_remove(struct dp_soc *soc,
uint16_t peer_id);
void dp_vdev_unref_delete(struct dp_soc *soc, struct dp_vdev *vdev,
enum dp_mod_id mod_id);
/*
* dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
* @peer: Datapath peer
*
* return: void
*/
void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer);
/*
* dp_peer_ppdu_delayed_ba_cleanup() free ppdu allocated in peer

View File

@@ -275,9 +275,6 @@ static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc,
/* Threshold for peer's cached buf queue beyond which frames are dropped */
#define DP_RX_CACHED_BUFQ_THRESH 64
/* Budget to reap monitor status ring */
#define DP_MON_REAP_BUDGET 1024
/**
* default_dscp_tid_map - Default DSCP-TID mapping
*
@@ -418,23 +415,6 @@ uint32_t dp_soc_get_mon_mask_for_interrupt_mode(struct dp_soc *soc, int intr_ctx
return 0;
}
/*
* dp_mon_reap_timer_handler()- timer to reap monitor rings
* reqd as we are not getting ppdu end interrupts
* @arg: SoC Handle
*
* Return:
*
*/
static void dp_mon_reap_timer_handler(void *arg)
{
struct dp_soc *soc = (struct dp_soc *)arg;
monitor_service_mon_rings(soc, QCA_NAPI_BUDGET);
qdf_timer_mod(&soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
}
/**
* dp_get_num_rx_contexts() - get number of RX contexts
* @soc_hdl: cdp opaque soc handle
@@ -2212,7 +2192,7 @@ static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc,
*
* Return: enum with yield code
*/
static enum timer_yield_status
enum timer_yield_status
dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
uint64_t start_time)
{
@@ -2227,6 +2207,8 @@ dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
return DP_TIMER_NO_YIELD;
}
qdf_export_symbol(dp_should_timer_irq_yield);
/**
* dp_process_lmac_rings() - Process LMAC rings
* @int_ctx: interrupt context
@@ -2447,7 +2429,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
int_ctx->intr_stats.num_reo_status_ring_masks++;
}
if (qdf_unlikely(!(soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING))) {
if (qdf_unlikely(!monitor_is_vdev_timer_running(soc))) {
work_done = dp_process_lmac_rings(int_ctx, remaining_quota);
if (work_done) {
budget -= work_done;
@@ -2488,7 +2470,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
int_ctx->intr_stats.num_reo_status_ring_masks++;
}
if (qdf_unlikely(!(soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING))) {
if (qdf_unlikely(!monitor_is_vdev_timer_running(soc))) {
work_done = dp_process_lmac_rings(int_ctx, remaining_quota);
if (work_done) {
budget -= work_done;
@@ -2507,70 +2489,6 @@ budget_done:
#endif /* QCA_HOST_MODE_WIFI_DISABLED */
/* dp_mon_vdev_timer()- timer poll for interrupts
*
* @arg: SoC Handle
*
* Return:
*
*/
static void dp_mon_vdev_timer(void *arg)
{
struct dp_soc *soc = (struct dp_soc *)arg;
struct dp_pdev *pdev = soc->pdev_list[0];
enum timer_yield_status yield = DP_TIMER_NO_YIELD;
uint32_t work_done = 0, total_work_done = 0;
int budget = 0xffff;
uint32_t remaining_quota = budget;
uint64_t start_time;
uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
uint32_t lmac_iter;
int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
if (!qdf_atomic_read(&soc->cmn_init_done))
return;
if (pdev->mon_chan_band != REG_BAND_UNKNOWN)
lmac_id = pdev->ch_band_lmac_id_mapping[pdev->mon_chan_band];
start_time = qdf_get_log_timestamp();
dp_is_hw_dbs_enable(soc, &max_mac_rings);
while (yield == DP_TIMER_NO_YIELD) {
for (lmac_iter = 0; lmac_iter < max_mac_rings; lmac_iter++) {
if (lmac_iter == lmac_id)
work_done = monitor_process(
soc, NULL,
lmac_iter, remaining_quota);
else
work_done =
monitor_drop_packets_for_mac(pdev,
lmac_iter,
remaining_quota);
if (work_done) {
budget -= work_done;
if (budget <= 0) {
yield = DP_TIMER_WORK_EXHAUST;
goto budget_done;
}
remaining_quota = budget;
total_work_done += work_done;
}
}
yield = dp_should_timer_irq_yield(soc, total_work_done,
start_time);
total_work_done = 0;
}
budget_done:
if (yield == DP_TIMER_WORK_EXHAUST ||
yield == DP_TIMER_TIME_EXHAUST)
qdf_timer_mod(&soc->mon_vdev_timer, 1);
else
qdf_timer_mod(&soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
}
/* dp_interrupt_timer()- timer poll for interrupts
*
* @arg: SoC Handle
@@ -4932,10 +4850,7 @@ static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev)
dp_srng_free(soc, &pdev->rx_mac_buf_ring[i]);
}
if (soc->reap_timer_init) {
qdf_timer_free(&soc->mon_reap_timer);
soc->reap_timer_init = 0;
}
monitor_reap_timer_deinit(soc);
}
#else
static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev)
@@ -5396,15 +5311,12 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
dp_soc_tx_history_detach(soc);
dp_soc_rx_history_detach(soc);
monitor_vdev_timer_deinit(soc);
if (!dp_monitor_modularized_enable()) {
dp_mon_soc_detach_wrapper(soc);
}
if (soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
qdf_timer_free(&soc->mon_vdev_timer);
soc->mon_vdev_timer_state = 0;
}
qdf_mem_free(soc);
}
@@ -5523,14 +5435,8 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc)
* Timer to reap rxdma status rings.
* Needed until we enable ppdu end interrupts
*/
qdf_timer_init(soc->osdev, &soc->mon_reap_timer,
dp_mon_reap_timer_handler, (void *)soc,
QDF_TIMER_TYPE_WAKE_APPS);
soc->reap_timer_init = 1;
qdf_timer_init(soc->osdev, &soc->mon_vdev_timer,
dp_mon_vdev_timer, (void *)soc,
QDF_TIMER_TYPE_WAKE_APPS);
soc->mon_vdev_timer_state |= MON_VDEV_TIMER_INIT;
monitor_reap_timer_init(soc);
monitor_vdev_timer_init(soc);
return status;
}
#else
@@ -5554,24 +5460,13 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc)
htt_srng_setup(soc->htt_handle, mac_for_pdev,
soc->rx_refill_buf_ring[lmac_id].
hal_srng, RXDMA_BUF);
#ifndef DISABLE_MON_CONFIG
if (soc->wlan_cfg_ctx->rxdma1_enable &&
wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) {
htt_srng_setup(soc->htt_handle, mac_for_pdev,
soc->rxdma_mon_buf_ring[lmac_id].hal_srng,
RXDMA_MONITOR_BUF);
htt_srng_setup(soc->htt_handle, mac_for_pdev,
soc->rxdma_mon_dst_ring[lmac_id].hal_srng,
RXDMA_MONITOR_DST);
htt_srng_setup(soc->htt_handle, mac_for_pdev,
soc->rxdma_mon_desc_ring[lmac_id].hal_srng,
RXDMA_MONITOR_DESC);
if (wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) {
/* Configure monitor mode rings */
monitor_htt_srng_setup(soc, pdev,
lmac_id,
mac_for_pdev);
}
htt_srng_setup(soc->htt_handle, mac_for_pdev,
soc->rxdma_mon_status_ring[lmac_id].hal_srng,
RXDMA_MONITOR_STATUS);
#endif
htt_srng_setup(soc->htt_handle, mac_for_pdev,
soc->rxdma_err_dst_ring[lmac_id].hal_srng,
RXDMA_DST);
@@ -5904,7 +5799,6 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
vdev->osif_rx = NULL;
vdev->osif_rsim_rx_decap = NULL;
vdev->osif_get_key = NULL;
vdev->osif_rx_mon = NULL;
vdev->osif_tx_free_ext = NULL;
vdev->osif_vdev = NULL;
@@ -5942,16 +5836,14 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
(wlan_op_mode_monitor == vdev->opmode))
qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
} else if (soc->intr_mode == DP_INTR_MSI &&
wlan_op_mode_monitor == vdev->opmode &&
soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
qdf_timer_mod(&soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
soc->mon_vdev_timer_state |= MON_VDEV_TIMER_RUNNING;
wlan_op_mode_monitor == vdev->opmode) {
monitor_vdev_timer_start(soc);
}
dp_vdev_id_map_tbl_add(soc, vdev, vdev_id);
if (wlan_op_mode_monitor == vdev->opmode) {
monitor_vdev_set_monitor_mode_buf_rings(pdev);
monitor_vdev_attach(vdev);
pdev->monitor_vdev = vdev;
return QDF_STATUS_SUCCESS;
}
@@ -6070,7 +5962,7 @@ static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc_hdl,
vdev->osif_fisa_rx = txrx_ops->rx.osif_fisa_rx;
vdev->osif_fisa_flush = txrx_ops->rx.osif_fisa_flush;
vdev->osif_get_key = txrx_ops->get_key;
vdev->osif_rx_mon = txrx_ops->rx.mon;
monitor_vdev_register_osif(vdev, txrx_ops);
vdev->osif_tx_free_ext = txrx_ops->tx.tx_free_ext;
vdev->tx_comp = txrx_ops->tx.tx_comp;
vdev->stats_cb = txrx_ops->rx.stats_rx;
@@ -6540,6 +6432,7 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
QDF_STATUS_SUCCESS)
dp_warn("peer ext_stats ctx alloc failed");
monitor_peer_attach(soc, peer);
/*
* In tx_monitor mode, filter may be set for unassociated peer
* when unassociated peer get associated peer need to
@@ -7189,18 +7082,11 @@ void dp_vdev_unref_delete(struct dp_soc *soc, struct dp_vdev *vdev,
vdev, QDF_MAC_ADDR_REF(vdev->mac_addr.raw));
if (wlan_op_mode_monitor == vdev->opmode) {
if (soc->intr_mode == DP_INTR_POLL) {
qdf_timer_sync_cancel(&soc->int_timer);
monitor_flush_rings(soc);
} else if (soc->intr_mode == DP_INTR_MSI &&
soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING) {
qdf_timer_sync_cancel(&soc->mon_vdev_timer);
monitor_flush_rings(soc);
soc->mon_vdev_timer_state &= ~MON_VDEV_TIMER_RUNNING;
}
monitor_vdev_delete(soc, vdev);
pdev->monitor_vdev = NULL;
goto free_vdev;
}
/* all peers are gone, go ahead and delete it */
dp_tx_flow_pool_unmap_handler(pdev, vdev_id,
FLOW_TYPE_VDEV, vdev_id);
@@ -7299,6 +7185,8 @@ void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id mod_id)
wlan_minidump_remove(peer, sizeof(*peer), soc->ctrl_psoc,
WLAN_MD_DP_PEER, "dp_peer");
monitor_peer_detach(soc, peer);
qdf_spin_lock_bh(&soc->inactive_peer_list_lock);
TAILQ_FOREACH(tmp_peer, &soc->inactive_peer_list,
inactive_list_elem) {
@@ -11446,10 +11334,9 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
/* Stop monitor reap timer and reap any pending frames in ring */
if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) ||
dp_is_enable_reap_timer_non_pkt(pdev)) &&
soc->reap_timer_init) {
qdf_timer_sync_cancel(&soc->mon_reap_timer);
monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
dp_is_enable_reap_timer_non_pkt(pdev))) {
if (monitor_reap_timer_stop(soc))
monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
}
dp_suspend_fse_cache_flush(soc);
@@ -11472,10 +11359,8 @@ static QDF_STATUS dp_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
/* Start monitor reap timer */
if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) ||
dp_is_enable_reap_timer_non_pkt(pdev)) &&
soc->reap_timer_init)
qdf_timer_mod(&soc->mon_reap_timer,
DP_INTR_POLL_TIMER_MS);
dp_is_enable_reap_timer_non_pkt(pdev)))
monitor_reap_timer_start(soc);
dp_resume_fse_cache_flush(soc);
@@ -11531,10 +11416,9 @@ static void dp_process_target_suspend_req(struct cdp_soc_t *soc_hdl,
/* Stop monitor reap timer and reap any pending frames in ring */
if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) ||
dp_is_enable_reap_timer_non_pkt(pdev)) &&
soc->reap_timer_init) {
qdf_timer_sync_cancel(&soc->mon_reap_timer);
monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
dp_is_enable_reap_timer_non_pkt(pdev))) {
if (monitor_reap_timer_stop(soc))
monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
}
}

View File

@@ -3311,32 +3311,6 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
#endif
}
#ifdef FEATURE_PERPKT_INFO
/*
* dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
* @peer: Datapath peer
*
* return: void
*/
void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
{
qdf_mem_zero(&peer->delayed_ba_ppdu_stats,
sizeof(struct cdp_delayed_tx_completion_ppdu_user));
peer->last_delayed_ba = false;
peer->last_delayed_ba_ppduid = 0;
}
#else
/*
* dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
* @peer: Datapath peer
*
* return: void
*/
void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
{
}
#endif
/*
* dp_peer_cleanup() Cleanup peer information
* @vdev: Datapath vdev

View File

@@ -1917,16 +1917,11 @@ struct dp_soc {
bool pending_ageout;
uint32_t max_ast_ageout_count;
/*interrupt timer*/
qdf_timer_t mon_reap_timer;
uint8_t reap_timer_init;
qdf_timer_t lmac_reap_timer;
uint8_t lmac_timer_init;
qdf_timer_t int_timer;
uint8_t intr_mode;
uint8_t lmac_polled_mode;
qdf_timer_t mon_vdev_timer;
uint8_t mon_vdev_timer_state;
qdf_list_t reo_desc_freelist;
qdf_spinlock_t reo_desc_freelist_lock;
@@ -2902,9 +2897,6 @@ struct dp_vdev {
/* proxy arp function */
ol_txrx_proxy_arp_fp osif_proxy_arp;
/* callback to hand rx monitor 802.11 MPDU to the OS shim */
ol_txrx_rx_mon_fp osif_rx_mon;
ol_txrx_mcast_me_fp me_convert;
/* completion function used by this vdev*/
@@ -3040,6 +3032,9 @@ struct dp_vdev {
uint8_t latency_tid;
} mesh_tid_latency_config;
#endif
#ifdef WIFI_MONITOR_SUPPORT
struct dp_mon_vdev *monitor_vdev;
#endif
#ifdef WLAN_FEATURE_TSF_UPLINK_DELAY
/* Indicate if uplink delay report is enabled or not */
@@ -3225,8 +3220,6 @@ struct dp_peer {
/* TID structures */
struct dp_rx_tid rx_tid[DP_MAX_TIDS];
struct dp_peer_tx_capture tx_capture;
/* TBD: No transmit TID state required? */
@@ -3303,14 +3296,6 @@ struct dp_peer {
qdf_atomic_t flush_in_progress;
struct dp_peer_cached_bufq bufq_info;
#endif
#ifdef FEATURE_PERPKT_INFO
/* delayed ba ppdu stats handling */
struct cdp_delayed_tx_completion_ppdu_user delayed_ba_ppdu_stats;
/* delayed ba flag */
bool last_delayed_ba;
/* delayed ba ppdu id */
uint32_t last_delayed_ba_ppduid;
#endif
#ifdef QCA_PEER_MULTIQ_SUPPORT
struct dp_peer_ast_params peer_ast_flowq_idx[DP_PEER_AST_FLOWQ_MAX];
#endif
@@ -3337,6 +3322,9 @@ struct dp_peer {
#ifdef WLAN_SUPPORT_MESH_LATENCY
struct dp_peer_mesh_latency_parameter mesh_latency_params[DP_MAX_TIDS];
#endif
#ifdef WIFI_MONITOR_SUPPORT
struct dp_mon_peer *monitor_peer;
#endif
};
/*

View File

@@ -58,8 +58,12 @@ QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng,
void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng,
int ring_type, int ring_num);
QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
uint8_t delayed_replenish);
enum timer_yield_status
dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
uint64_t start_time);
static QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
uint8_t delayed_replenish);
#ifndef WLAN_TX_PKT_CAPTURE_ENH
static inline void
@@ -1017,11 +1021,12 @@ dp_peer_copy_delay_stats(struct dp_peer *peer,
{
struct dp_pdev *pdev;
struct dp_vdev *vdev;
struct dp_mon_peer *mon_peer = peer->monitor_peer;
if (peer->last_delayed_ba) {
if (mon_peer->last_delayed_ba) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"BA not yet recv for prev delayed ppdu[%d] - cur ppdu[%d]",
peer->last_delayed_ba_ppduid, cur_ppdu_id);
mon_peer->last_delayed_ba_ppduid, cur_ppdu_id);
vdev = peer->vdev;
if (vdev) {
pdev = vdev->pdev;
@@ -1029,30 +1034,32 @@ dp_peer_copy_delay_stats(struct dp_peer *peer,
}
}
peer->delayed_ba_ppdu_stats.ltf_size = ppdu->ltf_size;
peer->delayed_ba_ppdu_stats.stbc = ppdu->stbc;
peer->delayed_ba_ppdu_stats.he_re = ppdu->he_re;
peer->delayed_ba_ppdu_stats.txbf = ppdu->txbf;
peer->delayed_ba_ppdu_stats.bw = ppdu->bw;
peer->delayed_ba_ppdu_stats.nss = ppdu->nss;
peer->delayed_ba_ppdu_stats.gi = ppdu->gi;
peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
peer->delayed_ba_ppdu_stats.ldpc = ppdu->ldpc;
peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
peer->delayed_ba_ppdu_stats.mpdu_tried_ucast = ppdu->mpdu_tried_ucast;
peer->delayed_ba_ppdu_stats.mpdu_tried_mcast = ppdu->mpdu_tried_mcast;
peer->delayed_ba_ppdu_stats.frame_ctrl = ppdu->frame_ctrl;
peer->delayed_ba_ppdu_stats.qos_ctrl = ppdu->qos_ctrl;
peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
mon_peer->delayed_ba_ppdu_stats.ltf_size = ppdu->ltf_size;
mon_peer->delayed_ba_ppdu_stats.stbc = ppdu->stbc;
mon_peer->delayed_ba_ppdu_stats.he_re = ppdu->he_re;
mon_peer->delayed_ba_ppdu_stats.txbf = ppdu->txbf;
mon_peer->delayed_ba_ppdu_stats.bw = ppdu->bw;
mon_peer->delayed_ba_ppdu_stats.nss = ppdu->nss;
mon_peer->delayed_ba_ppdu_stats.gi = ppdu->gi;
mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
mon_peer->delayed_ba_ppdu_stats.ldpc = ppdu->ldpc;
mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
mon_peer->delayed_ba_ppdu_stats.mpdu_tried_ucast =
ppdu->mpdu_tried_ucast;
mon_peer->delayed_ba_ppdu_stats.mpdu_tried_mcast =
ppdu->mpdu_tried_mcast;
mon_peer->delayed_ba_ppdu_stats.frame_ctrl = ppdu->frame_ctrl;
mon_peer->delayed_ba_ppdu_stats.qos_ctrl = ppdu->qos_ctrl;
mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
peer->delayed_ba_ppdu_stats.ru_start = ppdu->ru_start;
peer->delayed_ba_ppdu_stats.ru_tones = ppdu->ru_tones;
peer->delayed_ba_ppdu_stats.is_mcast = ppdu->is_mcast;
mon_peer->delayed_ba_ppdu_stats.ru_start = ppdu->ru_start;
mon_peer->delayed_ba_ppdu_stats.ru_tones = ppdu->ru_tones;
mon_peer->delayed_ba_ppdu_stats.is_mcast = ppdu->is_mcast;
peer->delayed_ba_ppdu_stats.user_pos = ppdu->user_pos;
peer->delayed_ba_ppdu_stats.mu_group_id = ppdu->mu_group_id;
mon_peer->delayed_ba_ppdu_stats.user_pos = ppdu->user_pos;
mon_peer->delayed_ba_ppdu_stats.mu_group_id = ppdu->mu_group_id;
peer->last_delayed_ba = true;
mon_peer->last_delayed_ba = true;
ppdu->debug_copied = true;
}
@@ -1074,30 +1081,34 @@ static void
dp_peer_copy_stats_to_bar(struct dp_peer *peer,
struct cdp_tx_completion_ppdu_user *ppdu)
{
ppdu->ltf_size = peer->delayed_ba_ppdu_stats.ltf_size;
ppdu->stbc = peer->delayed_ba_ppdu_stats.stbc;
ppdu->he_re = peer->delayed_ba_ppdu_stats.he_re;
ppdu->txbf = peer->delayed_ba_ppdu_stats.txbf;
ppdu->bw = peer->delayed_ba_ppdu_stats.bw;
ppdu->nss = peer->delayed_ba_ppdu_stats.nss;
ppdu->gi = peer->delayed_ba_ppdu_stats.gi;
ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm;
ppdu->ldpc = peer->delayed_ba_ppdu_stats.ldpc;
ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm;
ppdu->mpdu_tried_ucast = peer->delayed_ba_ppdu_stats.mpdu_tried_ucast;
ppdu->mpdu_tried_mcast = peer->delayed_ba_ppdu_stats.mpdu_tried_mcast;
ppdu->frame_ctrl = peer->delayed_ba_ppdu_stats.frame_ctrl;
ppdu->qos_ctrl = peer->delayed_ba_ppdu_stats.qos_ctrl;
ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm;
struct dp_mon_peer *mon_peer = peer->monitor_peer;
ppdu->ru_start = peer->delayed_ba_ppdu_stats.ru_start;
ppdu->ru_tones = peer->delayed_ba_ppdu_stats.ru_tones;
ppdu->is_mcast = peer->delayed_ba_ppdu_stats.is_mcast;
ppdu->ltf_size = mon_peer->delayed_ba_ppdu_stats.ltf_size;
ppdu->stbc = mon_peer->delayed_ba_ppdu_stats.stbc;
ppdu->he_re = mon_peer->delayed_ba_ppdu_stats.he_re;
ppdu->txbf = mon_peer->delayed_ba_ppdu_stats.txbf;
ppdu->bw = mon_peer->delayed_ba_ppdu_stats.bw;
ppdu->nss = mon_peer->delayed_ba_ppdu_stats.nss;
ppdu->gi = mon_peer->delayed_ba_ppdu_stats.gi;
ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
ppdu->ldpc = mon_peer->delayed_ba_ppdu_stats.ldpc;
ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
ppdu->mpdu_tried_ucast =
mon_peer->delayed_ba_ppdu_stats.mpdu_tried_ucast;
ppdu->mpdu_tried_mcast =
mon_peer->delayed_ba_ppdu_stats.mpdu_tried_mcast;
ppdu->frame_ctrl = mon_peer->delayed_ba_ppdu_stats.frame_ctrl;
ppdu->qos_ctrl = mon_peer->delayed_ba_ppdu_stats.qos_ctrl;
ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
ppdu->user_pos = peer->delayed_ba_ppdu_stats.user_pos;
ppdu->mu_group_id = peer->delayed_ba_ppdu_stats.mu_group_id;
ppdu->ru_start = mon_peer->delayed_ba_ppdu_stats.ru_start;
ppdu->ru_tones = mon_peer->delayed_ba_ppdu_stats.ru_tones;
ppdu->is_mcast = mon_peer->delayed_ba_ppdu_stats.is_mcast;
peer->last_delayed_ba = false;
ppdu->user_pos = mon_peer->delayed_ba_ppdu_stats.user_pos;
ppdu->mu_group_id = mon_peer->delayed_ba_ppdu_stats.mu_group_id;
mon_peer->last_delayed_ba = false;
ppdu->debug_copied = true;
}
@@ -2272,7 +2283,7 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
if (!peer)
continue;
delay_ppdu = &peer->delayed_ba_ppdu_stats;
delay_ppdu = &peer->monitor_peer->delayed_ba_ppdu_stats;
start_tsf = ppdu_desc->ppdu_start_timestamp;
end_tsf = ppdu_desc->ppdu_end_timestamp;
/**
@@ -2282,12 +2293,13 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
dp_peer_copy_delay_stats(peer,
&ppdu_desc->user[i],
ppdu_id);
peer->last_delayed_ba_ppduid = ppdu_id;
peer->monitor_peer->last_delayed_ba_ppduid =
ppdu_id;
delay_ppdu->ppdu_start_timestamp = start_tsf;
delay_ppdu->ppdu_end_timestamp = end_tsf;
}
ppdu_desc->user[i].peer_last_delayed_ba =
peer->last_delayed_ba;
peer->monitor_peer->last_delayed_ba;
dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
@@ -2334,20 +2346,20 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
continue;
}
delay_ppdu = &peer->delayed_ba_ppdu_stats;
delay_ppdu = &peer->monitor_peer->delayed_ba_ppdu_stats;
start_tsf = delay_ppdu->ppdu_start_timestamp;
end_tsf = delay_ppdu->ppdu_end_timestamp;
if (peer->last_delayed_ba) {
if (peer->monitor_peer->last_delayed_ba) {
dp_peer_copy_stats_to_bar(peer,
&ppdu_desc->user[i]);
ppdu_desc->ppdu_id =
peer->last_delayed_ba_ppduid;
peer->monitor_peer->last_delayed_ba_ppduid;
ppdu_desc->ppdu_start_timestamp = start_tsf;
ppdu_desc->ppdu_end_timestamp = end_tsf;
}
ppdu_desc->user[i].peer_last_delayed_ba =
peer->last_delayed_ba;
peer->monitor_peer->last_delayed_ba;
dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
}
}
@@ -3572,8 +3584,10 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
int max_mac_rings = wlan_cfg_get_num_mac_rings
(pdev->wlan_cfg_ctx);
uint8_t mac_id = 0;
struct dp_mon_soc *mon_soc;
soc = pdev->soc;
mon_soc = soc->monitor_soc;
dp_is_hw_dbs_enable(soc, &max_mac_rings);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
@@ -3603,9 +3617,9 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
return 0;
}
if (soc->reap_timer_init &&
if (mon_soc->reap_timer_init &&
(!dp_is_enable_reap_timer_non_pkt(pdev)))
qdf_timer_mod(&soc->mon_reap_timer,
qdf_timer_mod(&mon_soc->mon_reap_timer,
DP_INTR_POLL_TIMER_MS);
}
break;
@@ -3634,9 +3648,9 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
return 0;
}
if (soc->reap_timer_init &&
if (mon_soc->reap_timer_init &&
(!dp_is_enable_reap_timer_non_pkt(pdev)))
qdf_timer_mod(&soc->mon_reap_timer,
qdf_timer_mod(&mon_soc->mon_reap_timer,
DP_INTR_POLL_TIMER_MS);
}
break;
@@ -3682,9 +3696,9 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
return 0;
}
if (soc->reap_timer_init &&
if (mon_soc->reap_timer_init &&
!dp_is_enable_reap_timer_non_pkt(pdev))
qdf_timer_mod(&soc->mon_reap_timer,
qdf_timer_mod(&mon_soc->mon_reap_timer,
DP_INTR_POLL_TIMER_MS);
}
break;
@@ -3720,9 +3734,9 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
return 0;
}
if (soc->reap_timer_init &&
if (mon_soc->reap_timer_init &&
(!dp_is_enable_reap_timer_non_pkt(pdev)))
qdf_timer_stop(&soc->mon_reap_timer);
qdf_timer_stop(&mon_soc->mon_reap_timer);
}
break;
case WDI_EVENT_LITE_T2H:
@@ -3781,6 +3795,7 @@ static void dp_pktlogmod_exit(struct dp_pdev *pdev)
{
struct dp_soc *soc = pdev->soc;
struct hif_opaque_softc *scn = soc->hif_handle;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!scn) {
dp_err("Invalid hif(scn) handle");
@@ -3789,8 +3804,9 @@ static void dp_pktlogmod_exit(struct dp_pdev *pdev)
/* stop mon_reap_timer if it has been started */
if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED &&
soc->reap_timer_init && (!dp_is_enable_reap_timer_non_pkt(pdev)))
qdf_timer_sync_cancel(&soc->mon_reap_timer);
mon_soc->reap_timer_init &&
(!dp_is_enable_reap_timer_non_pkt(pdev)))
qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
pktlogmod_exit(scn);
pdev->pkt_log_init = false;
@@ -4183,6 +4199,7 @@ dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
{
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
struct dp_pdev *pdev = NULL;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
if (!pdev) {
@@ -4196,16 +4213,16 @@ dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
return;
}
if (!soc->reap_timer_init) {
if (!mon_soc->reap_timer_init) {
dp_err("reap timer not init");
return;
}
if (enable)
qdf_timer_mod(&soc->mon_reap_timer,
qdf_timer_mod(&mon_soc->mon_reap_timer,
DP_INTR_POLL_TIMER_MS);
else
qdf_timer_sync_cancel(&soc->mon_reap_timer);
qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
}
#endif
@@ -4488,8 +4505,8 @@ dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc,
*
* Return: QDF_STATUS
*/
QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
uint8_t delayed_replenish)
static QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
uint8_t delayed_replenish)
{
struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
uint32_t mac_id;
@@ -4564,6 +4581,168 @@ fail0:
return QDF_STATUS_E_FAILURE;
}
/* dp_mon_vdev_timer()- timer poll for interrupts
*
* @arg: SoC Handle
*
* Return:
*
*/
static void dp_mon_vdev_timer(void *arg)
{
struct dp_soc *soc = (struct dp_soc *)arg;
struct dp_pdev *pdev = soc->pdev_list[0];
enum timer_yield_status yield = DP_TIMER_NO_YIELD;
uint32_t work_done = 0, total_work_done = 0;
int budget = 0xffff;
uint32_t remaining_quota = budget;
uint64_t start_time;
uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
uint32_t lmac_iter;
int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!qdf_atomic_read(&soc->cmn_init_done))
return;
if (pdev->mon_chan_band != REG_BAND_UNKNOWN)
lmac_id = pdev->ch_band_lmac_id_mapping[pdev->mon_chan_band];
start_time = qdf_get_log_timestamp();
dp_is_hw_dbs_enable(soc, &max_mac_rings);
while (yield == DP_TIMER_NO_YIELD) {
for (lmac_iter = 0; lmac_iter < max_mac_rings; lmac_iter++) {
if (lmac_iter == lmac_id)
work_done = monitor_process(soc, NULL,
lmac_iter,
remaining_quota);
else
work_done =
monitor_drop_packets_for_mac(pdev,
lmac_iter,
remaining_quota);
if (work_done) {
budget -= work_done;
if (budget <= 0) {
yield = DP_TIMER_WORK_EXHAUST;
goto budget_done;
}
remaining_quota = budget;
total_work_done += work_done;
}
}
yield = dp_should_timer_irq_yield(soc, total_work_done,
start_time);
total_work_done = 0;
}
budget_done:
if (yield == DP_TIMER_WORK_EXHAUST ||
yield == DP_TIMER_TIME_EXHAUST)
qdf_timer_mod(&mon_soc->mon_vdev_timer, 1);
else
qdf_timer_mod(&mon_soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
}
/* MCL specific functions */
#if defined(DP_CON_MON)
/*
* dp_mon_reap_timer_handler()- timer to reap monitor rings
* reqd as we are not getting ppdu end interrupts
* @arg: SoC Handle
*
* Return:
*
*/
static void dp_mon_reap_timer_handler(void *arg)
{
struct dp_soc *soc = (struct dp_soc *)arg;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
dp_service_mon_rings(soc, QCA_NAPI_BUDGET);
qdf_timer_mod(&mon_soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
}
#endif
#ifdef QCA_HOST2FW_RXBUF_RING
static void dp_mon_reap_timer_init(struct dp_soc *soc)
{
struct dp_mon_soc *mon_soc = soc->monitor_soc;
qdf_timer_init(soc->osdev, &mon_soc->mon_reap_timer,
dp_mon_reap_timer_handler, (void *)soc,
QDF_TIMER_TYPE_WAKE_APPS);
mon_soc->reap_timer_init = 1;
}
#else
static void dp_mon_reap_timer_init(struct dp_soc *soc)
{
}
#endif
static void dp_mon_reap_timer_deinit(struct dp_mon_soc *mon_soc)
{
if (mon_soc->reap_timer_init) {
qdf_timer_free(&mon_soc->mon_reap_timer);
mon_soc->reap_timer_init = 0;
}
}
static void dp_mon_reap_timer_start(struct dp_mon_soc *mon_soc)
{
if (mon_soc->reap_timer_init)
qdf_timer_mod(&mon_soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
}
static bool dp_mon_reap_timer_stop(struct dp_mon_soc *mon_soc)
{
if (mon_soc->reap_timer_init) {
qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
return true;
}
return false;
}
static void dp_mon_vdev_timer_init(struct dp_soc *soc)
{
struct dp_mon_soc *mon_soc = soc->monitor_soc;
qdf_timer_init(soc->osdev, &mon_soc->mon_vdev_timer,
dp_mon_vdev_timer, (void *)soc,
QDF_TIMER_TYPE_WAKE_APPS);
mon_soc->mon_vdev_timer_state |= MON_VDEV_TIMER_INIT;
}
static void dp_mon_vdev_timer_deinit(struct dp_mon_soc *mon_soc)
{
if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
qdf_timer_free(&mon_soc->mon_vdev_timer);
mon_soc->mon_vdev_timer_state = 0;
}
}
static void dp_mon_vdev_timer_start(struct dp_mon_soc *mon_soc)
{
if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
qdf_timer_mod(&mon_soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
mon_soc->mon_vdev_timer_state |= MON_VDEV_TIMER_RUNNING;
}
}
static bool dp_mon_vdev_timer_stop(struct dp_mon_soc *mon_soc)
{
if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING) {
qdf_timer_sync_cancel(&mon_soc->mon_vdev_timer);
mon_soc->mon_vdev_timer_state &= ~MON_VDEV_TIMER_RUNNING;
return true;
}
return false;
}
QDF_STATUS dp_mon_soc_cfg_init(struct dp_soc *soc)
{
int target_type;
@@ -4746,12 +4925,67 @@ QDF_STATUS dp_mon_pdev_deinit(struct dp_pdev *pdev)
return QDF_STATUS_SUCCESS;
}
QDF_STATUS dp_mon_vdev_attach(struct dp_vdev *vdev)
{
struct dp_mon_vdev *mon_vdev;
struct dp_pdev *pdev = vdev->pdev;
mon_vdev = (struct dp_mon_vdev *)qdf_mem_malloc(sizeof(*mon_vdev));
if (!mon_vdev) {
mon_init_err("%pK: Monitor vdev allocation failed", vdev);
return QDF_STATUS_E_NOMEM;
}
vdev->monitor_vdev = mon_vdev;
dp_vdev_set_monitor_mode_buf_rings(pdev);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS dp_mon_vdev_detach(struct dp_vdev *vdev)
{
struct dp_mon_vdev *mon_vdev = vdev->monitor_vdev;
qdf_mem_free(mon_vdev);
vdev->monitor_vdev = NULL;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS dp_mon_peer_attach(struct dp_peer *peer)
{
struct dp_mon_peer *mon_peer;
mon_peer = (struct dp_mon_peer *)qdf_mem_malloc(sizeof(*mon_peer));
if (!mon_peer) {
mon_init_err("%pK: MONITOR peer allocation failed", peer);
return QDF_STATUS_E_NOMEM;
}
peer->monitor_peer = mon_peer;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS dp_mon_peer_detach(struct dp_peer *peer)
{
struct dp_mon_peer *mon_peer = peer->monitor_peer;
qdf_mem_free(mon_peer);
peer->monitor_peer = NULL;
return QDF_STATUS_SUCCESS;
}
static struct dp_mon_ops monitor_ops = {
.mon_soc_cfg_init = dp_mon_soc_cfg_init,
.mon_pdev_attach = dp_mon_pdev_attach,
.mon_pdev_detach = dp_mon_pdev_detach,
.mon_pdev_init = dp_mon_pdev_init,
.mon_pdev_deinit = dp_mon_pdev_deinit,
.mon_vdev_attach = dp_mon_vdev_attach,
.mon_vdev_detach = dp_mon_vdev_detach,
.mon_peer_attach = dp_mon_peer_attach,
.mon_peer_detach = dp_mon_peer_detach,
.mon_config_debug_sniffer = dp_config_debug_sniffer,
.mon_flush_rings = dp_flush_monitor_rings,
#if !defined(DISABLE_MON_CONFIG)
@@ -4812,6 +5046,14 @@ static struct dp_mon_ops monitor_ops = {
#ifdef FEATURE_NAC_RSSI
.mon_filter_neighbour_peer = dp_filter_neighbour_peer,
#endif
.mon_vdev_timer_init = dp_mon_vdev_timer_init,
.mon_vdev_timer_start = dp_mon_vdev_timer_start,
.mon_vdev_timer_stop = dp_mon_vdev_timer_stop,
.mon_vdev_timer_deinit = dp_mon_vdev_timer_deinit,
.mon_reap_timer_init = dp_mon_reap_timer_init,
.mon_reap_timer_start = dp_mon_reap_timer_start,
.mon_reap_timer_stop = dp_mon_reap_timer_stop,
.mon_reap_timer_deinit = dp_mon_reap_timer_deinit,
};
static struct cdp_mon_ops dp_ops_mon = {

View File

@@ -13,13 +13,26 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define DP_INTR_POLL_TIMER_MS 5
#define MON_VDEV_TIMER_INIT 0x1
#define MON_VDEV_TIMER_RUNNING 0x2
/* Budget to reap monitor status ring */
#define DP_MON_REAP_BUDGET 1024
#define mon_rx_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_DP_RX, params)
struct dp_mon_ops {
QDF_STATUS (*mon_soc_cfg_init)(struct dp_soc *soc);
QDF_STATUS (*mon_pdev_attach)(struct dp_pdev *pdev);
QDF_STATUS (*mon_pdev_detach)(struct dp_pdev *pdev);
QDF_STATUS (*mon_pdev_init)(struct dp_pdev *pdev);
QDF_STATUS (*mon_pdev_deinit)(struct dp_pdev *pdev);
QDF_STATUS (*mon_vdev_attach)(struct dp_vdev *vdev);
QDF_STATUS (*mon_vdev_detach)(struct dp_vdev *vdev);
QDF_STATUS (*mon_peer_attach)(struct dp_peer *peer);
QDF_STATUS (*mon_peer_detach)(struct dp_peer *peer);
QDF_STATUS (*mon_config_debug_sniffer)(struct dp_pdev *pdev, int val);
void (*mon_flush_rings)(struct dp_soc *soc);
#if !defined(DISABLE_MON_CONFIG)
@@ -100,12 +113,27 @@ struct dp_mon_ops {
QDF_STATUS (*mon_filter_neighbour_peer)(struct dp_pdev *pdev,
uint8_t *rx_pkt_hdr);
#endif
void (*mon_vdev_timer_init)(struct dp_soc *soc);
void (*mon_vdev_timer_start)(struct dp_mon_soc *mon_soc);
bool (*mon_vdev_timer_stop)(struct dp_mon_soc *mon_soc);
void (*mon_vdev_timer_deinit)(struct dp_mon_soc *mon_soc);
void (*mon_reap_timer_init)(struct dp_soc *soc);
void (*mon_reap_timer_start)(struct dp_mon_soc *mon_soc);
bool (*mon_reap_timer_stop)(struct dp_mon_soc *mon_soc);
void (*mon_reap_timer_deinit)(struct dp_mon_soc *mon_soc);
};
struct dp_mon_soc {
/* Holds all monitor related fields extracted from dp_soc */
/* Holds pointer to monitor ops */
/*interrupt timer*/
qdf_timer_t mon_reap_timer;
uint8_t reap_timer_init;
qdf_timer_t mon_vdev_timer;
uint8_t mon_vdev_timer_state;
struct dp_mon_ops *mon_ops;
};
@@ -113,9 +141,20 @@ struct dp_mon_pdev {
};
struct dp_mon_vdev {
/* callback to hand rx monitor 802.11 MPDU to the OS shim */
ol_txrx_rx_mon_fp osif_rx_mon;
};
struct dp_mon_peer {
struct dp_peer_tx_capture tx_capture;
#ifdef FEATURE_PERPKT_INFO
/* delayed ba ppdu stats handling */
struct cdp_delayed_tx_completion_ppdu_user delayed_ba_ppdu_stats;
/* delayed ba flag */
bool last_delayed_ba;
/* delayed ba ppdu id */
uint32_t last_delayed_ba_ppduid;
#endif
};
#ifdef FEATURE_PERPKT_INFO
@@ -227,6 +266,19 @@ extern uint8_t
dp_cpu_ring_map[DP_NSS_CPU_RING_MAP_MAX][WLAN_CFG_INT_NUM_CONTEXTS_MAX];
#endif
int
dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap);
/**
* dp_ppdu_desc_user_stats_update(): Function to update TX user stats
* @pdev: DP pdev handle
* @ppdu_info: per PPDU TLV descriptor
*
* return: void
*/
void
dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
struct ppdu_info *ppdu_info);
#ifdef WDI_EVENT_ENABLE
void dp_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn);
#else
@@ -324,6 +376,58 @@ static inline QDF_STATUS monitor_drop_inv_peer_pkts(struct dp_vdev *vdev,
}
#endif
#ifdef FEATURE_PERPKT_INFO
/*
* dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
* @peer: Datapath peer
*
* return: void
*/
static inline void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
{
struct dp_mon_peer *mon_peer = peer->monitor_peer;
if (!mon_peer)
return;
qdf_mem_zero(&mon_peer->delayed_ba_ppdu_stats,
sizeof(struct cdp_delayed_tx_completion_ppdu_user));
mon_peer->last_delayed_ba = false;
mon_peer->last_delayed_ba_ppduid = 0;
}
#else
/*
* dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
* @peer: Datapath peer
*
* return: void
*/
static inline void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
{
}
#endif
static inline void monitor_vdev_register_osif(struct dp_vdev *vdev,
struct ol_txrx_ops *txrx_ops)
{
if (!vdev->monitor_vdev)
return;
vdev->monitor_vdev->osif_rx_mon = txrx_ops->rx.mon;
}
static inline bool monitor_is_vdev_timer_running(struct dp_soc *soc)
{
struct dp_mon_soc *mon_soc;
if (!soc || !soc->monitor_soc)
return false;
mon_soc = soc->monitor_soc;
return mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING;
}
static inline QDF_STATUS monitor_pdev_attach(struct dp_pdev *pdev)
{
struct dp_mon_ops *monitor_ops;
@@ -368,6 +472,76 @@ static inline QDF_STATUS monitor_pdev_detach(struct dp_pdev *pdev)
return monitor_ops->mon_pdev_detach(pdev);
}
static inline QDF_STATUS monitor_vdev_attach(struct dp_vdev *vdev)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = vdev->pdev->soc->monitor_soc;
if (!mon_soc)
return QDF_STATUS_E_FAILURE;
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_vdev_attach) {
qdf_err("callback not registered");
return QDF_STATUS_E_FAILURE;
}
return monitor_ops->mon_vdev_attach(vdev);
}
static inline QDF_STATUS monitor_vdev_detach(struct dp_vdev *vdev)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = vdev->pdev->soc->monitor_soc;
if (!mon_soc)
return QDF_STATUS_E_FAILURE;
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_vdev_detach) {
qdf_err("callback not registered");
return QDF_STATUS_E_FAILURE;
}
return monitor_ops->mon_vdev_detach(vdev);
}
static inline QDF_STATUS monitor_peer_attach(struct dp_soc *soc,
struct dp_peer *peer)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc)
return QDF_STATUS_E_FAILURE;
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_peer_attach) {
qdf_print("callback not registered");
return QDF_STATUS_E_FAILURE;
}
return monitor_ops->mon_peer_attach(peer);
}
static inline QDF_STATUS monitor_peer_detach(struct dp_soc *soc,
struct dp_peer *peer)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc)
return QDF_STATUS_E_FAILURE;
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_peer_detach) {
qdf_print("callback not registered");
return QDF_STATUS_E_FAILURE;
}
return monitor_ops->mon_peer_detach(peer);
}
static inline QDF_STATUS monitor_pdev_init(struct dp_pdev *pdev)
{
struct dp_mon_ops *monitor_ops;
@@ -1221,3 +1395,177 @@ static inline QDF_STATUS monitor_filter_neighbour_peer(struct dp_pdev *pdev,
return monitor_ops->mon_filter_neighbour_peer(pdev, rx_pkt_hdr);
}
#endif
static inline
void monitor_reap_timer_init(struct dp_soc *soc)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc) {
qdf_err("monitor soc is NULL");
return;
}
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_reap_timer_init) {
qdf_err("callback not registered");
return;
}
monitor_ops->mon_reap_timer_init(soc);
}
static inline
void monitor_reap_timer_deinit(struct dp_soc *soc)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc) {
qdf_err("monitor soc is NULL");
return;
}
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_reap_timer_deinit) {
qdf_err("callback not registered");
return;
}
monitor_ops->mon_reap_timer_deinit(mon_soc);
}
static inline
void monitor_reap_timer_start(struct dp_soc *soc)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc) {
qdf_err("monitor soc is NULL");
return;
}
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_reap_timer_start) {
qdf_err("callback not registered");
return;
}
monitor_ops->mon_reap_timer_start(mon_soc);
}
static inline
bool monitor_reap_timer_stop(struct dp_soc *soc)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc) {
qdf_err("monitor soc is NULL");
return false;
}
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_reap_timer_stop) {
qdf_err("callback not registered");
return false;
}
monitor_ops->mon_reap_timer_stop(mon_soc);
}
static inline
void monitor_vdev_timer_init(struct dp_soc *soc)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc) {
qdf_err("monitor soc is NULL");
return;
}
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_vdev_timer_init) {
qdf_err("callback not registered");
return;
}
monitor_ops->mon_vdev_timer_init(soc);
}
static inline
void monitor_vdev_timer_deinit(struct dp_soc *soc)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc) {
qdf_err("monitor soc is NULL");
return;
}
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_vdev_timer_deinit) {
qdf_err("callback not registered");
return;
}
monitor_ops->mon_vdev_timer_deinit(mon_soc);
}
static inline
void monitor_vdev_timer_start(struct dp_soc *soc)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc) {
qdf_err("monitor soc is NULL");
return;
}
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_vdev_timer_start) {
qdf_err("callback not registered");
return;
}
monitor_ops->mon_vdev_timer_start(mon_soc);
}
static inline
bool monitor_vdev_timer_stop(struct dp_soc *soc)
{
struct dp_mon_ops *monitor_ops;
struct dp_mon_soc *mon_soc = soc->monitor_soc;
if (!mon_soc) {
qdf_err("monitor soc is NULL");
return false;
}
monitor_ops = mon_soc->mon_ops;
if (!monitor_ops || !monitor_ops->mon_vdev_timer_stop) {
qdf_err("callback not registered");
return false;
}
return monitor_ops->mon_vdev_timer_stop(mon_soc);
}
static inline void monitor_vdev_delete(struct dp_soc *soc, struct dp_vdev *vdev)
{
if (soc->intr_mode == DP_INTR_POLL) {
qdf_timer_sync_cancel(&soc->int_timer);
monitor_flush_rings(soc);
} else if (soc->intr_mode == DP_INTR_MSI) {
if (monitor_vdev_timer_stop(soc))
monitor_flush_rings(soc);
}
monitor_vdev_detach(vdev);
}

View File

@@ -25,6 +25,8 @@
#include "qdf_trace.h"
#include "qdf_nbuf.h"
#include "hal_api_mon.h"
#include "dp_htt.h"
#include "dp_mon.h"
#include "dp_rx_mon.h"
#include "wlan_cfg.h"
#include "dp_internal.h"
@@ -1489,11 +1491,13 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
struct cdp_mon_status *rs = &pdev->rx_mon_recv_status;
qdf_nbuf_t mon_skb, skb_next;
qdf_nbuf_t mon_mpdu = NULL;
struct dp_vdev *vdev;
if (!pdev || (!pdev->monitor_vdev && !pdev->mcopy_mode &&
!pdev->rx_pktlog_cbf))
goto mon_deliver_fail;
vdev = pdev->monitor_vdev;
/* restitch mon MPDU for delivery via monitor interface */
mon_mpdu = dp_rx_mon_restitch_mpdu(soc, mac_id, head_msdu,
tail_msdu, rs);
@@ -1513,7 +1517,7 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
return dp_send_mgmt_packet_to_stack(soc, mon_mpdu, pdev);
if (mon_mpdu && pdev->monitor_vdev && pdev->monitor_vdev->osif_vdev &&
pdev->monitor_vdev->osif_rx_mon) {
vdev->monitor_vdev->osif_rx_mon) {
pdev->ppdu_info.rx_status.ppdu_id =
pdev->ppdu_info.com_info.ppdu_id;
pdev->ppdu_info.rx_status.device_id = soc->device_id;
@@ -1532,7 +1536,7 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
}
dp_rx_mon_update_pf_tag_to_buf_headroom(soc, mon_mpdu);
pdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
vdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
mon_mpdu,
&pdev->ppdu_info.rx_status);
} else {
@@ -1575,13 +1579,19 @@ QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc,
struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
ol_txrx_rx_mon_fp osif_rx_mon;
qdf_nbuf_t dummy_msdu;
struct dp_vdev *vdev;
/* Sanity checking */
if (!pdev || !pdev->monitor_vdev || !pdev->monitor_vdev->osif_rx_mon)
if (!pdev || !pdev->monitor_vdev)
goto mon_deliver_non_std_fail;
vdev = pdev->monitor_vdev;
if (!vdev->monitor_vdev->osif_rx_mon)
goto mon_deliver_non_std_fail;
/* Generate a dummy skb_buff */
osif_rx_mon = pdev->monitor_vdev->osif_rx_mon;
osif_rx_mon = vdev->monitor_vdev->osif_rx_mon;
dummy_msdu = qdf_nbuf_alloc(soc->osdev, MAX_MONITOR_HEADER,
MAX_MONITOR_HEADER, 4, FALSE);
if (!dummy_msdu)

View File

@@ -1092,6 +1092,7 @@ dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
qdf_nbuf_t nbuf)
{
uint8_t size = 0;
struct dp_vdev *vdev;
if (!pdev->monitor_vdev) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
@@ -1099,6 +1100,9 @@ dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
__func__, __LINE__);
return 1;
}
vdev = pdev->monitor_vdev;
if (!ppdu_info->msdu_info.first_msdu_payload) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"[%s]:[%d] First msdu payload not present",
@@ -1127,7 +1131,7 @@ dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
return 1;
}
pdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
vdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
nbuf, NULL);
pdev->ppdu_info.rx_status.monitor_direct_used = 0;
return 0;