Merge "qca-wifi: Fix for tx capture softlockup on mode change"
diff --git a/dp/wifi3.0/dp_tx_capture.c b/dp/wifi3.0/dp_tx_capture.c
index 5cb8105..390a12f 100644
--- a/dp/wifi3.0/dp_tx_capture.c
+++ b/dp/wifi3.0/dp_tx_capture.c
@@ -525,7 +525,7 @@
bool found = false;
found = dp_peer_tx_cap_search(pdev, peer_id, mac_addr);
- QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_HIGH,
"%s: %d peer_id[%d] mac_addr[%pM] found[%d]!",
__func__, __LINE__, peer_id, mac_addr, found);
@@ -545,6 +545,7 @@
int i, j;
tx_capture = &pdev->tx_capture;
+ tx_capture->tx_cap_mode_flag = true;
/* Work queue setup for HTT stats and tx capture handling */
qdf_create_work(0, &pdev->tx_capture.ppdu_stats_work,
dp_tx_ppdu_stats_process,
@@ -937,6 +938,44 @@
}
/*
+ * dp_enh_tx_capture_disable()- API to disable enhanced tx capture
+ * @pdev_handle: DP_PDEV handle
+ *
+ * Return: void
+ */
+void
+dp_enh_tx_capture_disable(struct dp_pdev *pdev)
+{
+ int i, j;
+
+ dp_soc_set_txrx_ring_map(pdev->soc);
+ dp_h2t_cfg_stats_msg_send(pdev,
+ DP_PPDU_STATS_CFG_ENH_STATS,
+ pdev->pdev_id);
+ dp_iterate_free_peer_msdu_q(pdev);
+ for (i = 0; i < TXCAP_MAX_TYPE; i++) {
+ for (j = 0; j < TXCAP_MAX_SUBTYPE; j++) {
+ qdf_nbuf_queue_t *retries_q;
+
+ qdf_spin_lock_bh(
+ &pdev->tx_capture.ctl_mgmt_lock[i][j]);
+ qdf_nbuf_queue_free(
+ &pdev->tx_capture.ctl_mgmt_q[i][j]);
+ qdf_spin_unlock_bh(
+ &pdev->tx_capture.ctl_mgmt_lock[i][j]);
+ retries_q = &pdev->tx_capture.retries_ctl_mgmt_q[i][j];
+ if (!qdf_nbuf_is_queue_empty(retries_q))
+ qdf_nbuf_queue_free(retries_q);
+ }
+ }
+ dp_peer_tx_cap_del_all_filter(pdev);
+ pdev->tx_capture.tx_cap_mode_flag = true;
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "Mode change request done cur mode - %d\n",
+ pdev->tx_capture_enabled);
+}
+
+/*
* dp_config_enh_tx_capture()- API to enable/disable enhanced tx capture
* @pdev_handle: DP_PDEV handle
* @val: user provided value
@@ -946,10 +985,28 @@
QDF_STATUS
dp_config_enh_tx_capture(struct dp_pdev *pdev, uint8_t val)
{
- int i, j;
-
qdf_spin_lock(&pdev->tx_capture.config_lock);
- pdev->tx_capture_enabled = val;
+ if (pdev->tx_capture.tx_cap_mode_flag) {
+ pdev->tx_capture.tx_cap_mode_flag = false;
+ pdev->tx_capture_enabled = val;
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "Mode change requested - %d\n",
+ pdev->tx_capture_enabled);
+ } else if (!pdev->tx_capture.tx_cap_mode_flag &&
+ !val && !!pdev->tx_capture_enabled) {
+ /* here the val is always 0 which is disable */
+ pdev->tx_capture_enabled = val;
+ pdev->tx_capture.tx_cap_mode_flag = false;
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "Mode change requested - %d\n",
+ pdev->tx_capture_enabled);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "Mode change request pending prev mode - %d\n",
+ pdev->tx_capture_enabled);
+ qdf_spin_unlock(&pdev->tx_capture.config_lock);
+ return QDF_STATUS_E_BUSY;
+ }
if (pdev->tx_capture_enabled == CDP_TX_ENH_CAPTURE_ENABLE_ALL_PEERS ||
pdev->tx_capture_enabled == CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER) {
@@ -958,26 +1015,13 @@
dp_h2t_cfg_stats_msg_send(pdev,
DP_PPDU_STATS_CFG_SNIFFER,
pdev->pdev_id);
- } else {
- dp_soc_set_txrx_ring_map(pdev->soc);
- dp_h2t_cfg_stats_msg_send(pdev,
- DP_PPDU_STATS_CFG_ENH_STATS,
- pdev->pdev_id);
- dp_iterate_free_peer_msdu_q(pdev);
- for (i = 0; i < TXCAP_MAX_TYPE; i++) {
- for (j = 0; j < TXCAP_MAX_SUBTYPE; j++) {
- qdf_spin_lock_bh(
- &pdev->tx_capture.ctl_mgmt_lock[i][j]);
- qdf_nbuf_queue_free(
- &pdev->tx_capture.ctl_mgmt_q[i][j]);
- qdf_spin_unlock_bh(
- &pdev->tx_capture.ctl_mgmt_lock[i][j]);
- }
- }
- dp_peer_tx_cap_del_all_filter(pdev);
+ pdev->tx_capture.tx_cap_mode_flag = true;
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "Mode change request done cur mode - %d\n",
+ pdev->tx_capture_enabled);
}
-
qdf_spin_unlock(&pdev->tx_capture.config_lock);
+
return QDF_STATUS_SUCCESS;
}
@@ -3168,6 +3212,9 @@
/* send WDI event */
if (pdev->tx_capture_enabled ==
CDP_TX_ENH_CAPTURE_DISABLED) {
+ if (!pdev->tx_capture.tx_cap_mode_flag)
+ dp_enh_tx_capture_disable(pdev);
+
/**
* Deliver PPDU stats only for valid (acked)
* data frames if sniffer mode is not enabled.
@@ -3360,6 +3407,11 @@
qdf_spin_unlock(&ptr_tx_cap->config_lock);
qdf_mem_free(nbuf_ppdu_desc_list);
+
+ qdf_spin_lock(&pdev->tx_capture.config_lock);
+ if (!pdev->tx_capture.tx_cap_mode_flag)
+ dp_enh_tx_capture_disable(pdev);
+ qdf_spin_unlock(&pdev->tx_capture.config_lock);
}
}
diff --git a/dp/wifi3.0/dp_tx_capture.h b/dp/wifi3.0/dp_tx_capture.h
index 016675c..52bc8c4 100644
--- a/dp/wifi3.0/dp_tx_capture.h
+++ b/dp/wifi3.0/dp_tx_capture.h
@@ -71,6 +71,7 @@
uint32_t htt_frame_type[TX_CAP_HTT_MAX_FTYPE];
struct cdp_tx_completion_ppdu dummy_ppdu_desc;
struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+ bool tx_cap_mode_flag;
};
/* Tx TID */