diff --git a/components/p2p/core/src/wlan_p2p_off_chan_tx.c b/components/p2p/core/src/wlan_p2p_off_chan_tx.c index 3eb625152743..c094cd389c4e 100644 --- a/components/p2p/core/src/wlan_p2p_off_chan_tx.c +++ b/components/p2p/core/src/wlan_p2p_off_chan_tx.c @@ -1337,18 +1337,38 @@ end: */ static void p2p_tx_timeout(void *pdata) { - struct tx_action_context *tx_ctx = pdata; + QDF_STATUS status, ret; + qdf_list_node_t *p_node; + struct tx_action_context *tx_ctx; + struct p2p_soc_priv_obj *p2p_soc_obj; p2p_info("pdata:%pK", pdata); - - if (!tx_ctx || !(tx_ctx->p2p_soc_obj)) { - p2p_err("invalid tx context or p2p soc object"); + p2p_soc_obj = (struct p2p_soc_priv_obj *)pdata; + if (!p2p_soc_obj) { + p2p_err("null p2p soc obj"); return; } - qdf_mc_timer_destroy(&tx_ctx->tx_timer); - p2p_send_tx_conf(tx_ctx, false); - p2p_remove_tx_context(tx_ctx); + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, + p_node, &p_node); + if (QDF_TIMER_STATE_STOPPED == + qdf_mc_timer_get_current_state(&tx_ctx->tx_timer)) { + ret = qdf_list_remove_node(&p2p_soc_obj->tx_q_ack, + &tx_ctx->node); + if (ret == QDF_STATUS_SUCCESS) { + qdf_mc_timer_destroy(&tx_ctx->tx_timer); + p2p_send_tx_conf(tx_ctx, false); + qdf_mem_free(tx_ctx->buf); + qdf_mem_free(tx_ctx); + } else + p2p_err("remove %pK from roc_q fail", + tx_ctx); + } + } } /** @@ -1366,15 +1386,15 @@ static QDF_STATUS p2p_enable_tx_timer(struct tx_action_context *tx_ctx) p2p_debug("tx context:%pK", tx_ctx); status = qdf_mc_timer_init(&tx_ctx->tx_timer, - QDF_TIMER_TYPE_SW, p2p_tx_timeout, - tx_ctx); + QDF_TIMER_TYPE_SW, p2p_tx_timeout, + tx_ctx->p2p_soc_obj); if (status != QDF_STATUS_SUCCESS) { p2p_err("failed to init tx timer"); return status; } status = qdf_mc_timer_start(&tx_ctx->tx_timer, - P2P_ACTION_FRAME_TX_TIMEOUT); + P2P_ACTION_FRAME_TX_TIMEOUT); if (status != QDF_STATUS_SUCCESS) p2p_err("tx timer start failed"); @@ -1648,10 +1668,6 @@ struct tx_action_context *p2p_find_tx_ctx_by_nbuf( qdf_container_of(p_node, struct tx_action_context, node); if (cur_tx_ctx->nbuf == nbuf) { p2p_debug("find tx ctx, nbuf:%pK", nbuf); - status = qdf_mc_timer_stop(&cur_tx_ctx->tx_timer); - if (status != QDF_STATUS_SUCCESS) - p2p_err("Failed to stop tx timer, status:%d", - status); return cur_tx_ctx; } status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, @@ -2902,6 +2918,8 @@ QDF_STATUS p2p_process_mgmt_tx_ack_cnf( return QDF_STATUS_SUCCESS; } + /* disable tx timer */ + p2p_disable_tx_timer(tx_ctx); tx_cnf.vdev_id = tx_ctx->vdev_id; tx_cnf.action_cookie = (uint64_t)tx_ctx->id; tx_cnf.buf = tx_ctx->buf; @@ -2915,9 +2933,6 @@ QDF_STATUS p2p_process_mgmt_tx_ack_cnf( p2p_rand_mac_tx_done(p2p_soc_obj->soc, tx_ctx); - /* disable tx timer */ - p2p_disable_tx_timer(tx_ctx); - start_param = p2p_soc_obj->start_param; if (start_param->tx_cnf_cb) start_param->tx_cnf_cb(start_param->tx_cnf_cb_data,