diff --git a/umac/p2p/core/src/wlan_p2p_off_chan_tx.c b/umac/p2p/core/src/wlan_p2p_off_chan_tx.c index 51e8492ac5..0b6b6d249f 100644 --- a/umac/p2p/core/src/wlan_p2p_off_chan_tx.c +++ b/umac/p2p/core/src/wlan_p2p_off_chan_tx.c @@ -932,9 +932,10 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, mgmt_param.frm_len, mgmt_param.vdev_id, mgmt_param.chanfreq, tx_ctx->no_ack); - status = wlan_mgmt_txrx_mgmt_frame_tx(peer, tx_ctx, - (qdf_nbuf_t)packet, - tx_comp_cb, tx_ota_comp_cb, + tx_ctx->nbuf = packet; + + status = wlan_mgmt_txrx_mgmt_frame_tx(peer, tx_ctx->p2p_soc_obj, + (qdf_nbuf_t)packet, tx_comp_cb, tx_ota_comp_cb, WLAN_UMAC_COMP_P2P, &mgmt_param); wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID); @@ -1138,7 +1139,6 @@ static QDF_STATUS p2p_move_tx_context_to_ack_queue( &tx_ctx->node); if (status != QDF_STATUS_SUCCESS) p2p_err("Failed to insert off chan tx context to wait ack req queue"); - p2p_debug("insert tx context to wait for roc queue, status:%d", status); @@ -1286,8 +1286,8 @@ static void p2p_tx_timeout(void *pdata) p2p_debug("pdata:%pK", pdata); - if (!tx_ctx) { - p2p_err("invalid tx context"); + if (!tx_ctx || !(tx_ctx->p2p_soc_obj)) { + p2p_err("invalid tx context or p2p soc object"); return; } @@ -1456,6 +1456,37 @@ static QDF_STATUS p2p_execute_tx_action_frame( return status; } +struct tx_action_context *p2p_find_tx_ctx_by_nbuf( + struct p2p_soc_priv_obj *p2p_soc_obj, void *nbuf) +{ + struct tx_action_context *cur_tx_ctx; + qdf_list_node_t *p_node; + QDF_STATUS status; + + if (!p2p_soc_obj) { + p2p_err("invalid p2p soc object"); + return NULL; + } + + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + cur_tx_ctx = + 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, + p_node, &p_node); + } + + return NULL; +} + void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) { struct tx_action_context *tx_ctx; diff --git a/umac/p2p/core/src/wlan_p2p_off_chan_tx.h b/umac/p2p/core/src/wlan_p2p_off_chan_tx.h index 39f006b7e0..87465875f0 100644 --- a/umac/p2p/core/src/wlan_p2p_off_chan_tx.h +++ b/umac/p2p/core/src/wlan_p2p_off_chan_tx.h @@ -173,6 +173,7 @@ struct tx_action_context { uint32_t duration; qdf_mc_timer_t tx_timer; struct p2p_frame_info frame_info; + void *nbuf; }; /** @@ -255,4 +256,16 @@ QDF_STATUS p2p_process_mgmt_tx_ack_cnf( QDF_STATUS p2p_process_rx_mgmt( struct p2p_rx_mgmt_event *rx_mgmt_event); +/** + * p2p_find_tx_ctx_by_nbuf() - find tx context by nbuf + * @p2p_soc_obj: p2p soc object + * @nbuf: pointer to nbuf + * + * This function finds out tx context by nbuf. + * + * Return: pointer to tx context + */ +struct tx_action_context *p2p_find_tx_ctx_by_nbuf( + struct p2p_soc_priv_obj *p2p_soc_obj, void *nbuf); + #endif /* _WLAN_P2P_OFF_CHAN_TX_H_ */ diff --git a/umac/p2p/dispatcher/src/wlan_p2p_tgt_api.c b/umac/p2p/dispatcher/src/wlan_p2p_tgt_api.c index 699bd47071..84cd4673a5 100644 --- a/umac/p2p/dispatcher/src/wlan_p2p_tgt_api.c +++ b/umac/p2p/dispatcher/src/wlan_p2p_tgt_api.c @@ -137,8 +137,13 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, qdf_nbuf_free(buf); return QDF_STATUS_E_INVAL; } - tx_ctx = (struct tx_action_context *)context; - p2p_soc_obj = tx_ctx->p2p_soc_obj; + p2p_soc_obj = (struct p2p_soc_priv_obj *)context; + tx_ctx = p2p_find_tx_ctx_by_nbuf(p2p_soc_obj, buf); + if (!tx_ctx) { + p2p_err("can't find tx_ctx, tx ack comes late"); + qdf_nbuf_free(buf); + return QDF_STATUS_E_FAULT; + } tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event)); if (!tx_conf_event) { diff --git a/umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c b/umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c index a59469282e..4415b3cbef 100644 --- a/umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/umac/p2p/dispatcher/src/wlan_p2p_ucfg_api.c @@ -271,6 +271,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, return QDF_STATUS_E_NOMEM; } qdf_mem_copy(tx_action->buf, mgmt_frm->buf, tx_action->buf_len); + tx_action->nbuf = NULL; msg.type = P2P_MGMT_TX; msg.bodyptr = tx_action; msg.callback = p2p_process_cmd;