OSI: Set Tx IOC for every fixed number of descs

A new field 'use_tx_descs' gets programmed by OSD layer.
Tx ring accounts current desc counts and when the current desc
count increases above use_tx_descs and the last bit is set
in the desc, we set the IOC bit.

Bug 4569357

Change-Id: Ida2c7b84e0096007b874e79e3b7502c997f71980
Signed-off-by: Aniruddha Paul <anpaul@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3207582
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: svcacv <svcacv@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com>
This commit is contained in:
Aniruddha Paul
2024-09-04 11:34:08 +00:00
committed by mobile promotions
parent 22a75ac576
commit fc6e9530b6
2 changed files with 23 additions and 1 deletions

View File

@@ -616,6 +616,10 @@ struct osi_tx_ring {
* this value will be restarted. This parameter is internal to this unit only. * this value will be restarted. This parameter is internal to this unit only.
*/ */
nveu32_t frame_cnt; 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 */ /** flag to skip memory barrier. Valid values are 1 or 0 */
nveu32_t skip_dmb; nveu32_t skip_dmb;
}; };
@@ -768,11 +772,20 @@ struct osi_dma_priv_data {
* Max value is NVETHERNETCL_PIF$UINT_MAX * Max value is NVETHERNETCL_PIF$UINT_MAX
*/ */
nveu32_t tx_frames; 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 /** Flag which decides tx_frames is
* NVETHERNETCL_PIF$OSI_ENABLE or * NVETHERNETCL_PIF$OSI_ENABLE or
* NVETHERNETCL_PIF$OSI_DISABLE * NVETHERNETCL_PIF$OSI_DISABLE
*/ */
nveu32_t use_tx_frames; 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 */ /** DMA callback ops structure */
struct osd_dma_ops osd_ops; struct osd_dma_ops osd_ops;
#ifndef OSI_STRIPPED_LIB #ifndef OSI_STRIPPED_LIB

View File

@@ -1052,7 +1052,6 @@ static inline void update_frame_cnt(struct osi_dma_priv_data *osi_dma,
} else { } else {
tx_ring->frame_cnt = 1U; tx_ring->frame_cnt = 1U;
} }
} }
static inline void apply_write_barrier(struct osi_tx_ring *tx_ring) 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) { if ((tx_ring->frame_cnt % osi_dma->tx_frames) == OSI_NONE) {
last_desc->tdes2 |= TDES2_IOC; 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; first_desc = tx_desc;
last_desc = tx_desc; last_desc = tx_desc;
last_swcx = tx_swcx; last_swcx = tx_swcx;
tx_desc = tx_ring->tx_desc + entry; tx_desc = tx_ring->tx_desc + entry;
tx_swcx = tx_ring->tx_swcx + entry; tx_swcx = tx_ring->tx_swcx + entry;
desc_cnt--; desc_cnt--;
/* Fill remaining descriptors */ /* Fill remaining descriptors */
for (i = 0; i < desc_cnt; i++) { 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->tdes0 = L32(tx_swcx->buf_phy_addr);
tx_desc->tdes1 = H32(tx_swcx->buf_phy_addr); tx_desc->tdes1 = H32(tx_swcx->buf_phy_addr);
tx_desc->tdes2 = tx_swcx->len; 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; last_desc->tdes2 |= TDES2_IOC;
update_frame_cnt(osi_dma, tx_ring); update_frame_cnt(osi_dma, tx_ring);
tx_ring->desc_cnt++;
set_clear_ioc_for_last_desc(osi_dma, tx_ring, last_desc); set_clear_ioc_for_last_desc(osi_dma, tx_ring, last_desc);