From a89ce48ab20f4507cfb6f8d86861403f3fa208c2 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran Date: Mon, 15 Jun 2020 11:02:36 -0700 Subject: [PATCH] nvethernetrm: Indicate more Rx frames pending Issue: The function osi_process_rx_completions does not provide indication whether there are more Rx frames in the HW ring to be processed by SW. This indication is needed in OSD layers like AUTOSAR MCAL driver as per the spec. Fix: Check the next descriptor in the ring and indicate if it has a valid new Rx packet that is pending to be processed. Bug 3019362 Change-Id: I4b4b8ac7b741dedbe979156e44f442cbb0e67590 Signed-off-by: Srinivas Ramachandran Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2361176 Reviewed-by: Bhadram Varka Reviewed-by: Mahesh Patil Reviewed-by: automaticguardword Reviewed-by: Ashutosh Jha Reviewed-by: mobile promotions Tested-by: Mahesh Patil Tested-by: mobile promotions GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 5 ++++- osi/dma/osi_dma_txrx.c | 25 +++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 0b80ba4..59cf44b 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -750,6 +750,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * @param[in] osi: OSI private data structure. * @param[in] chan: Rx DMA channel number * @param[in] budget: Threshould for reading the packets at a time. + * @param[in] more_data_avail: Pointer to more data available flag. OSI fills + * this flag if more rx packets available to read(1) or not(0). * * @note * 1) MAC needs to be out of reset and proper clocks need to be configured. @@ -759,7 +761,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * @returns Number of decriptors (buffers) proccessed. */ int osi_process_rx_completions(struct osi_dma_priv_data *osi, - unsigned int chan, int budget); + unsigned int chan, int budget, + unsigned int *more_data_avail); /** * @brief osi_hw_dma_init - Initialize DMA diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 3a35619..d97bb1e 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -234,7 +234,8 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, } int osi_process_rx_completions(struct osi_dma_priv_data *osi, - unsigned int chan, int budget) + unsigned int chan, int budget, + unsigned int *more_data_avail) { struct osi_rx_ring *rx_ring = osi->rx_ring[chan]; struct osi_rx_pkt_cx *rx_pkt_cx = &rx_ring->rx_pkt_cx; @@ -245,10 +246,13 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, int received = 0; int ret = 0; - if (rx_ring->cur_rx_idx >= RX_DESC_CNT) { + if (rx_ring->cur_rx_idx >= RX_DESC_CNT || more_data_avail == OSI_NULL) { return -1; } + /* Reset flag to indicate if more Rx frames available to OSD layer */ + *more_data_avail = OSI_NONE; + while (received < budget) { osi_memset(rx_pkt_cx, 0U, sizeof(*rx_pkt_cx)); rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; @@ -332,6 +336,23 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, osi->dstats.rx_pkt_n = osi_update_stats_counter(osi->dstats.rx_pkt_n, 1UL); received++; + + /* If budget is done, check if HW ring still has unprocessed + * Rx packets, so that the OSD layer can decide to schedule + * this function again. + */ + if (received == budget) { + rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; + rx_swcx = rx_ring->rx_swcx + rx_ring->cur_rx_idx; + if (((rx_swcx->flags & OSI_RX_SWCX_PROCESSED) != + OSI_RX_SWCX_PROCESSED) && + ((rx_desc->rdes3 & RDES3_OWN) != RDES3_OWN)) { + /* Next desciptor has owned by SW + * So set more data avail flag here. + */ + *more_data_avail = OSI_ENABLE; + } + } } return received;