diff --git a/include/osi_dma.h b/include/osi_dma.h index a5502cc..a61eb7e 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -616,6 +616,10 @@ struct osi_tx_ring { * this value will be restarted. This parameter is internal to this unit only. */ nveu32_t frame_cnt; + /** Total number of desc count. Incremented for every decriptor used. This + * adjusted for every delta greater than equal to intr_desc_count. + */ + nveu32_t desc_cnt; /** flag to skip memory barrier. Valid values are 1 or 0 */ nveu32_t skip_dmb; }; @@ -768,11 +772,20 @@ struct osi_dma_priv_data { * Max value is NVETHERNETCL_PIF$UINT_MAX */ nveu32_t tx_frames; + /** Max no of descs to transfer before triggering Tx interrupt. + * Max value is NVETHERNETCL_PIF$UINT_MAX + */ + nveu32_t intr_desc_count; /** Flag which decides tx_frames is * NVETHERNETCL_PIF$OSI_ENABLE or * NVETHERNETCL_PIF$OSI_DISABLE */ nveu32_t use_tx_frames; + /** Flag which decides Tx timer is + * NVETHERNETCL_PIF$OSI_ENABLE or + * NVETHERNETCL_PIF$OSI_DISABLE + */ + nveu32_t use_tx_descs; /** DMA callback ops structure */ struct osd_dma_ops osd_ops; #ifndef OSI_STRIPPED_LIB diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 862e83d..0490c50 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1052,7 +1052,6 @@ static inline void update_frame_cnt(struct osi_dma_priv_data *osi_dma, } else { tx_ring->frame_cnt = 1U; } - } static inline void apply_write_barrier(struct osi_tx_ring *tx_ring) @@ -1093,6 +1092,11 @@ static inline void set_clear_ioc_for_last_desc(struct osi_dma_priv_data *osi_dma if ((tx_ring->frame_cnt % osi_dma->tx_frames) == OSI_NONE) { last_desc->tdes2 |= TDES2_IOC; } + } else if (osi_dma->use_tx_descs == OSI_ENABLE) { + if (tx_ring->desc_cnt >= osi_dma->intr_desc_count) { + last_desc->tdes2 |= TDES2_IOC; + tx_ring->desc_cnt = tx_ring->desc_cnt % osi_dma->intr_desc_count; + } } } } @@ -1222,12 +1226,16 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, first_desc = tx_desc; last_desc = tx_desc; last_swcx = tx_swcx; + tx_desc = tx_ring->tx_desc + entry; tx_swcx = tx_ring->tx_swcx + entry; desc_cnt--; /* Fill remaining descriptors */ for (i = 0; i < desc_cnt; i++) { + /* Increase the desc count for first descriptor */ + tx_ring->desc_cnt++; + tx_desc->tdes0 = L32(tx_swcx->buf_phy_addr); tx_desc->tdes1 = H32(tx_swcx->buf_phy_addr); tx_desc->tdes2 = tx_swcx->len; @@ -1250,6 +1258,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, last_desc->tdes2 |= TDES2_IOC; update_frame_cnt(osi_dma, tx_ring); + tx_ring->desc_cnt++; set_clear_ioc_for_last_desc(osi_dma, tx_ring, last_desc);