qcacmn: Take peer reference before requesting for rx queue status

Increase the peer ref count before requesting for reo
queue stats and release the ref count after receiving
the queue stats on the reo status srng.

Change-Id: Ife3b87951e767414efa1bfb45486cd364578d2a7
CRs-Fixed: 2604862
This commit is contained in:
Venkata Sharath Chandra Manchala
2020-01-17 14:46:19 -08:00
committed by nshrivas
parent e8a1cf3c70
commit 0094761c88
5 changed files with 62 additions and 92 deletions

View File

@@ -780,27 +780,8 @@ cdp_txrx_ext_stats_request(ol_txrx_soc_handle soc, uint8_t pdev_id,
*
* return: none
*/
static inline void
cdp_request_rx_hw_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
{
if (!soc || !soc->ops || !soc->ops->misc_ops) {
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
"%s: Invalid Instance:", __func__);
return;
}
if (soc->ops->misc_ops->request_rx_hw_stats)
soc->ops->misc_ops->request_rx_hw_stats(soc, vdev_id);
}
/**
* cdp_wait_for_ext_rx_stats(): wait for reo command status for stats
* @soc: soc handle
*
* return: status
*/
static inline QDF_STATUS
cdp_wait_for_ext_rx_stats(ol_txrx_soc_handle soc)
cdp_request_rx_hw_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
{
if (!soc || !soc->ops || !soc->ops->misc_ops) {
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
@@ -808,10 +789,9 @@ cdp_wait_for_ext_rx_stats(ol_txrx_soc_handle soc)
return QDF_STATUS_E_INVAL;
}
if (soc->ops->misc_ops->wait_for_ext_rx_stats)
return soc->ops->misc_ops->wait_for_ext_rx_stats(soc);
if (soc->ops->misc_ops->request_rx_hw_stats)
return soc->ops->misc_ops->request_rx_hw_stats(soc, vdev_id);
return QDF_STATUS_SUCCESS;
}
#endif /* _CDP_TXRX_MISC_H_ */

View File

@@ -1209,8 +1209,8 @@ struct cdp_misc_ops {
QDF_STATUS (*txrx_ext_stats_request)(struct cdp_soc_t *soc_hdl,
uint8_t pdev_id,
struct cdp_txrx_ext_stats *req);
void (*request_rx_hw_stats)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id);
QDF_STATUS (*wait_for_ext_rx_stats)(struct cdp_soc_t *soc_hdl);
QDF_STATUS (*request_rx_hw_stats)(struct cdp_soc_t *soc_hdl,
uint8_t vdev_id);
};
/**

View File

@@ -5491,26 +5491,6 @@ static inline void dp_peer_rx_bufq_resources_init(struct dp_peer *peer)
}
#endif
#ifdef WLAN_FEATURE_STATS_EXT
/*
* dp_set_ignore_reo_status_cb() - set ignore reo status cb flag
* @soc: dp soc handle
* @flag: flag to set or reset
*
* Return: None
*/
static inline void dp_set_ignore_reo_status_cb(struct dp_soc *soc,
bool flag)
{
soc->ignore_reo_status_cb = flag;
}
#else
static inline void dp_set_ignore_reo_status_cb(struct dp_soc *soc,
bool flag)
{
}
#endif
/*
* dp_peer_create_wifi3() - attach txrx peer
* @soc_hdl: Datapath soc handle
@@ -5677,12 +5657,6 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
vdev->vap_self_peer = peer;
}
if (wlan_op_mode_sta == vdev->opmode &&
qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw,
QDF_MAC_ADDR_SIZE) != 0) {
dp_set_ignore_reo_status_cb(soc, false);
}
for (i = 0; i < DP_MAX_TIDS; i++)
qdf_spinlock_create(&peer->rx_tid[i].tid_lock);
@@ -6262,8 +6236,11 @@ static void dp_vdev_reset_peer(struct dp_vdev *vdev,
if (!vdev) {
dp_err("vdev is NULL");
} else {
if (vdev->vap_bss_peer == peer)
if (vdev->vap_bss_peer == peer) {
vdev->vap_bss_peer = NULL;
qdf_mem_zero(vdev->vap_bss_peer_mac_addr,
QDF_MAC_ADDR_SIZE);
}
if (vdev && vdev->vap_bss_peer) {
bss_peer = vdev->vap_bss_peer;
@@ -6530,12 +6507,6 @@ static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
qdf_spinlock_destroy(&peer->peer_info_lock);
dp_peer_multipass_list_remove(peer);
if (wlan_op_mode_sta == peer->vdev->opmode &&
qdf_mem_cmp(peer->mac_addr.raw, peer->vdev->mac_addr.raw,
QDF_MAC_ADDR_SIZE) != 0) {
dp_set_ignore_reo_status_cb(peer->vdev->pdev->soc, true);
}
/*
* Remove the reference added during peer_attach.
* The peer will still be left allocated until the
@@ -10367,6 +10338,39 @@ dp_txrx_post_data_stall_event(struct cdp_soc_t *soc_hdl,
}
#endif /* WLAN_SUPPORT_DATA_STALL */
#ifdef DP_PEER_EXTENDED_API
/**
* dp_peer_get_ref_find_by_addr - get peer with addr by ref count inc
* @dev: physical device instance
* @peer_mac_addr: peer mac address
* @debug_id: to track enum peer access
*
* Return: peer instance pointer
*/
static void *
dp_peer_get_ref_find_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr,
enum peer_debug_id_type debug_id)
{
struct dp_pdev *pdev = (struct dp_pdev *)dev;
struct dp_peer *peer;
peer = dp_peer_find_hash_find(pdev->soc, peer_mac_addr, 0, DP_VDEV_ALL);
if (!peer)
return NULL;
if (peer->delete_in_progress) {
dp_err("Peer deletion in progress");
dp_peer_unref_delete(peer);
return NULL;
}
dp_info_rl("peer %pK mac: %pM", peer, peer->mac_addr.raw);
return peer;
}
#endif /* DP_PEER_EXTENDED_API */
#ifdef WLAN_FEATURE_STATS_EXT
/* rx hw stats event wait timeout in ms */
#define DP_REO_STATUS_STATS_TIMEOUT 1000
@@ -10417,11 +10421,6 @@ static void dp_rx_hw_stats_cb(struct dp_soc *soc, void *cb_ctxt,
struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
struct hal_reo_queue_status *queue_status = &reo_status->queue_status;
if (soc->ignore_reo_status_cb) {
qdf_event_set(&soc->rx_hw_stats_event);
return;
}
if (queue_status->header.status != HAL_REO_CMD_SUCCESS) {
dp_info("REO stats failure %d for TID %d",
queue_status->header.status, rx_tid->tid);
@@ -10442,46 +10441,35 @@ static void dp_rx_hw_stats_cb(struct dp_soc *soc, void *cb_ctxt,
*
* Return: None
*/
static void
static QDF_STATUS
dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
{
struct dp_soc *soc = (struct dp_soc *)soc_hdl;
struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
struct dp_peer *peer;
QDF_STATUS status;
if (!vdev) {
dp_err("vdev is null");
qdf_event_set(&soc->rx_hw_stats_event);
return;
dp_err("vdev is null for vdev_id: %u", vdev_id);
return QDF_STATUS_E_INVAL;
}
peer = vdev->vap_bss_peer;
peer = dp_peer_get_ref_find_by_addr((struct cdp_pdev *)vdev->pdev,
vdev->vap_bss_peer_mac_addr, 0);
if (!peer || peer->delete_in_progress) {
dp_err("Peer deletion in progress");
qdf_event_set(&soc->rx_hw_stats_event);
return;
if (!peer) {
dp_err("Peer is NULL");
return QDF_STATUS_E_INVAL;
}
qdf_event_reset(&soc->rx_hw_stats_event);
dp_peer_rxtid_stats(peer, dp_rx_hw_stats_cb, NULL);
}
/**
* dp_wait_for_ext_rx_stats - wait for rx reo status for rx stats
* @soc_hdl: cdp opaque soc handle
*
* Return: status
*/
static QDF_STATUS
dp_wait_for_ext_rx_stats(struct cdp_soc_t *soc_hdl)
{
struct dp_soc *soc = (struct dp_soc *)soc_hdl;
QDF_STATUS status;
status = qdf_wait_single_event(&soc->rx_hw_stats_event,
DP_REO_STATUS_STATS_TIMEOUT);
dp_peer_unref_delete(peer);
return status;
}
#endif /* WLAN_FEATURE_STATS_EXT */
@@ -10509,8 +10497,7 @@ static struct cdp_misc_ops dp_ops_misc = {
#ifdef WLAN_FEATURE_STATS_EXT
.txrx_ext_stats_request = dp_txrx_ext_stats_request,
.request_rx_hw_stats = dp_request_rx_hw_stats,
.wait_for_ext_rx_stats = dp_wait_for_ext_rx_stats,
#endif
#endif /* WLAN_FEATURE_STATS_EXT */
};
#endif

View File

@@ -1583,6 +1583,9 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
dp_info("STA vdev bss_peer!!!!");
peer->bss_peer = 1;
peer->vdev->vap_bss_peer = peer;
qdf_mem_copy(peer->vdev->vap_bss_peer_mac_addr,
peer->mac_addr.raw,
QDF_MAC_ADDR_SIZE);
}
if (peer->vdev->opmode == wlan_op_mode_sta) {

View File

@@ -1209,10 +1209,7 @@ struct dp_soc {
uint32_t rx_mpdu_missed;
} ext_stats;
qdf_event_t rx_hw_stats_event;
/* Ignore reo command queue status during peer delete */
bool ignore_reo_status_cb;
#endif
#endif /* WLAN_FEATURE_STATS_EXT */
/* Smart monitor capability for HKv2 */
uint8_t hw_nac_monitor_support;
@@ -1993,6 +1990,9 @@ struct dp_vdev {
bool peer_protocol_count_track;
int peer_protocol_count_dropmask;
#endif
/* vap bss peer mac addr */
uint8_t vap_bss_peer_mac_addr[QDF_MAC_ADDR_SIZE];
};