diff --git a/dp/wifi3.0/be/dp_be_tx.c b/dp/wifi3.0/be/dp_be_tx.c index ee58e734c5..f39c581d64 100644 --- a/dp/wifi3.0/be/dp_be_tx.c +++ b/dp/wifi3.0/be/dp_be_tx.c @@ -367,7 +367,7 @@ void dp_tx_process_htt_completion_be(struct dp_soc *soc, dp_tx_comp_process_tx_status(soc, tx_desc, &ts, txrx_peer, ring_id); dp_tx_comp_process_desc(soc, tx_desc, &ts, txrx_peer); - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id); if (qdf_likely(txrx_peer)) dp_txrx_peer_unref_delete(txrx_ref_handle, @@ -407,7 +407,7 @@ void dp_tx_process_htt_completion_be(struct dp_soc *soc, release_tx_desc: dp_tx_comp_free_buf(soc, tx_desc, false); - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id); if (vdev) dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP); } @@ -1899,7 +1899,7 @@ ring_access_fail2: return NULL; release_desc: - dp_tx_desc_release(tx_desc, desc_pool_id); + dp_tx_desc_release(soc, tx_desc, desc_pool_id); return nbuf; } diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index c9a63e9de1..101ceae2cf 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -11138,7 +11138,8 @@ void dp_find_missing_tx_comp(struct dp_soc *soc) dp_tx_comp_free_buf(soc, tx_desc, false); - dp_tx_desc_release(tx_desc, i); + dp_tx_desc_release(soc, tx_desc, + i); DP_STATS_INC(soc, tx.tx_comp_force_freed, 1); } diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index f50be74404..6a12f2242a 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -356,13 +356,39 @@ static void dp_tx_tso_desc_release(struct dp_soc *soc, } #endif +#ifdef WLAN_SUPPORT_PPEDS +static inline int +dp_tx_release_ds_tx_desc(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, + uint8_t desc_pool_id) +{ + if (tx_desc->flags & DP_TX_DESC_FLAG_PPEDS) { + __dp_tx_outstanding_dec(soc); + dp_tx_desc_free(soc, tx_desc, desc_pool_id); + + return 1; + } + + return 0; +} +#else +static inline int +dp_tx_release_ds_tx_desc(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, + uint8_t desc_pool_id) +{ + return 0; +} +#endif + void -dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id) +dp_tx_desc_release(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, + uint8_t desc_pool_id) { struct dp_pdev *pdev = tx_desc->pdev; - struct dp_soc *soc; uint8_t comp_status = 0; + if (dp_tx_release_ds_tx_desc(soc, tx_desc, desc_pool_id)) + return; + qdf_assert(pdev); soc = pdev->soc; @@ -1259,7 +1285,7 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev, return tx_desc; failure: - dp_tx_desc_release(tx_desc, desc_pool_id); + dp_tx_desc_release(soc, tx_desc, desc_pool_id); return NULL; } @@ -1345,7 +1371,7 @@ static struct dp_tx_desc_s *dp_tx_prepare_desc(struct dp_vdev *vdev, return tx_desc; failure: - dp_tx_desc_release(tx_desc, desc_pool_id); + dp_tx_desc_release(soc, tx_desc, desc_pool_id); return NULL; } @@ -2410,7 +2436,7 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, return NULL; release_desc: - dp_tx_desc_release(tx_desc, tx_q->desc_pool_id); + dp_tx_desc_release(soc, tx_desc, tx_q->desc_pool_id); fail_return: dp_tx_get_tid(vdev, nbuf, msdu_info); @@ -2728,7 +2754,8 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, */ qdf_nbuf_free(msdu_info->u.sg_info .curr_seg->nbuf); - dp_tx_desc_release(tx_desc, tx_q->desc_pool_id); + dp_tx_desc_release(soc, tx_desc, + tx_q->desc_pool_id); if (msdu_info->u.sg_info.curr_seg->next) { msdu_info->u.sg_info.curr_seg = msdu_info->u.sg_info @@ -2754,14 +2781,15 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf, */ dp_tx_comp_free_buf(soc, tx_desc, false); i++; - dp_tx_desc_release(tx_desc, tx_q->desc_pool_id); + dp_tx_desc_release(soc, tx_desc, + tx_q->desc_pool_id); continue; } if (msdu_info->frm_type == dp_tx_frm_sg) dp_tx_sg_unmap_buf(soc, nbuf, msdu_info); - dp_tx_desc_release(tx_desc, tx_q->desc_pool_id); + dp_tx_desc_release(soc, tx_desc, tx_q->desc_pool_id); goto done; } @@ -3838,7 +3866,7 @@ dp_tx_reinject_mlo_hdl(struct dp_soc *soc, struct dp_vdev *vdev, if (soc->arch_ops.dp_tx_mcast_handler) soc->arch_ops.dp_tx_mcast_handler(soc, vdev, nbuf); - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id); return true; } @@ -3982,7 +4010,7 @@ void dp_tx_reinject_handler(struct dp_soc *soc, qdf_nbuf_free(nbuf); } - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id); } void dp_tx_inspect_handler(struct dp_soc *soc, @@ -3999,7 +4027,7 @@ void dp_tx_inspect_handler(struct dp_soc *soc, qdf_nbuf_len(tx_desc->nbuf)); DP_TX_FREE_SINGLE_BUF(soc, tx_desc->nbuf); - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id); } #ifdef MESH_MODE_SUPPORT @@ -5481,7 +5509,7 @@ dp_tx_mcast_reinject_handler(struct dp_soc *soc, struct dp_tx_desc_s *desc) DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1, qdf_nbuf_len(desc->nbuf)); soc->arch_ops.dp_tx_mcast_handler(soc, vdev, desc->nbuf); - dp_tx_desc_release(desc, desc->pool_id); + dp_tx_desc_release(soc, desc, desc->pool_id); dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_REINJECT); return true; } @@ -5690,7 +5718,7 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc, dp_tx_comp_process_desc(soc, desc, &ts, txrx_peer); - dp_tx_desc_release(desc, desc->pool_id); + dp_tx_desc_release(soc, desc, desc->pool_id); desc = next; } dp_tx_nbuf_dev_kfree_list(&h); @@ -5943,7 +5971,8 @@ more_data: tx_desc->id); tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR; dp_tx_comp_free_buf(soc, tx_desc, false); - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, + tx_desc->pool_id); goto next_desc; } @@ -6126,6 +6155,26 @@ void dp_tx_vdev_update_search_flags(struct dp_vdev *vdev) vdev->search_type = HAL_TX_ADDR_SEARCH_DEFAULT; } +#ifdef WLAN_SUPPORT_PPEDS +static inline bool +dp_is_tx_desc_flush_match(struct dp_pdev *pdev, + struct dp_vdev *vdev, + struct dp_tx_desc_s *tx_desc) +{ + if (!(tx_desc && (tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED))) + return false; + + if (tx_desc->flags & DP_TX_DESC_FLAG_PPEDS) + return true; + /* + * if vdev is given, then only check whether desc + * vdev match. if vdev is NULL, then check whether + * desc pdev match. + */ + return vdev ? (tx_desc->vdev_id == vdev->vdev_id) : + (tx_desc->pdev == pdev); +} +#else static inline bool dp_is_tx_desc_flush_match(struct dp_pdev *pdev, struct dp_vdev *vdev, @@ -6142,6 +6191,7 @@ dp_is_tx_desc_flush_match(struct dp_pdev *pdev, return vdev ? (tx_desc->vdev_id == vdev->vdev_id) : (tx_desc->pdev == pdev); } +#endif #ifdef QCA_LL_TX_FLOW_CONTROL_V2 void dp_tx_desc_flush(struct dp_pdev *pdev, struct dp_vdev *vdev, @@ -6201,7 +6251,7 @@ void dp_tx_desc_flush(struct dp_pdev *pdev, struct dp_vdev *vdev, tx_desc->flags |= DP_TX_DESC_FLAG_FLUSH; dp_tx_comp_free_buf(soc, tx_desc, false); - dp_tx_desc_release(tx_desc, i); + dp_tx_desc_release(soc, tx_desc, i); } else { tx_desc->vdev_id = DP_INVALID_VDEV_ID; } @@ -6263,10 +6313,9 @@ void dp_tx_desc_flush(struct dp_pdev *pdev, struct dp_vdev *vdev, if (dp_is_tx_desc_flush_match(pdev, vdev, tx_desc)) { if (force_free) { - tx_desc->flags |= DP_TX_DESC_FLAG_FLUSH; dp_tx_comp_free_buf(soc, tx_desc, false); - dp_tx_desc_release(tx_desc, i); + dp_tx_desc_release(soc, tx_desc, i); } else { dp_tx_desc_reset_vdev(soc, tx_desc, i); diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h index 9c18d1c395..5070a99325 100644 --- a/dp/wifi3.0/dp_tx.h +++ b/dp/wifi3.0/dp_tx.h @@ -287,6 +287,7 @@ qdf_nbuf_t dp_tx_comp_free_buf(struct dp_soc *soc, struct dp_tx_desc_s *desc, /** * dp_tx_desc_release() - Release Tx Descriptor + * @soc: Soc handle * @tx_desc: Tx Descriptor * @desc_pool_id: Descriptor Pool ID * @@ -295,7 +296,8 @@ qdf_nbuf_t dp_tx_comp_free_buf(struct dp_soc *soc, struct dp_tx_desc_s *desc, * * Return: */ -void dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id); +void dp_tx_desc_release(struct dp_soc *soc, struct dp_tx_desc_s *tx_desc, + uint8_t desc_pool_id); /** * dp_tx_compute_delay() - Compute and fill in all timestamps diff --git a/dp/wifi3.0/dp_tx_desc.c b/dp/wifi3.0/dp_tx_desc.c index d3755c49f0..f0474a8009 100644 --- a/dp/wifi3.0/dp_tx_desc.c +++ b/dp/wifi3.0/dp_tx_desc.c @@ -81,7 +81,7 @@ static void dp_tx_desc_clean_up(void *ctxt, void *elem, void *elem_list) if (tx_desc->nbuf) { nbuf = dp_tx_comp_free_buf(soc, tx_desc, true); - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id); if (nbuf) { if (!nbuf_list) { diff --git a/dp/wifi3.0/li/dp_li_tx.c b/dp/wifi3.0/li/dp_li_tx.c index fdf7bc089b..3a50e8ae9a 100644 --- a/dp/wifi3.0/li/dp_li_tx.c +++ b/dp/wifi3.0/li/dp_li_tx.c @@ -214,7 +214,7 @@ void dp_tx_process_htt_completion_li(struct dp_soc *soc, dp_tx_comp_process_tx_status(soc, tx_desc, &ts, txrx_peer, ring_id); dp_tx_comp_process_desc(soc, tx_desc, &ts, txrx_peer); - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id); if (qdf_likely(txrx_peer)) dp_txrx_peer_unref_delete(txrx_ref_handle, @@ -254,7 +254,7 @@ void dp_tx_process_htt_completion_li(struct dp_soc *soc, release_tx_desc: dp_tx_comp_free_buf(soc, tx_desc, false); - dp_tx_desc_release(tx_desc, tx_desc->pool_id); + dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id); if (vdev) dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP); }