osi: single API to handle DMA interrupts

Issue: Currently there are multiple API's for
handling DMA interrupts.

Fix: Creating single API to handle DMA interrupts.

Bug 200671160

Change-Id: I9385e8fb0ca044c7a01d38483226e2e83f76f5b9
Signed-off-by: Bhadram Varka <vbhadram@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2497610
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Bhadram Varka
2021-03-12 13:40:38 +05:30
committed by mobile promotions
parent cde6a3320f
commit b7a5f00fb4
4 changed files with 109 additions and 0 deletions

View File

@@ -182,6 +182,19 @@
/** @} */
/**
* @addtogroup OSI-INTR OSI DMA interrupt handling macros.
*
* @brief Macros to pass osi_handle_dma_intr() API to handle
* the interrupts between OSI and OSD.
* @{
*/
#define OSI_DMA_CH_TX_INTR 0U
#define OSI_DMA_CH_RX_INTR 1U
#define OSI_DMA_INTR_DISABLE 0U
#define OSI_DMA_INTR_ENABLE 1U
/** @} */
/**
* @brief OSI packet error stats
*/
@@ -1201,6 +1214,49 @@ nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma,
*/
nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma);
/**
* @brief osi_handle_dma_intr - Handles DMA interrupts.
*
* @note
* Algorithm:
* - Enables/Disables DMA CH TX/RX/VM inetrrupts.
*
* @param[in] osi_dma: OSI DMA private data.
* @param[in] chan: DMA Rx channel number. Max OSI_EQOS_MAX_NUM_CHANS.
* @param[in] tx_rx: Indicates whether DMA channel is Tx or Rx.
* OSI_DMA_CH_TX_INTR for Tx interrupt.
* OSI_DMA_CH_RX_INTR for Rx interrupt.
* @param[in] en_dis: Enable/Disable DMA channel interrupts.
* OSI_DMA_INTR_DISABLE for disabling the interrupt.
* OSI_DMA_INTR_ENABLE for enabling the interrupt.
*
* @pre
* - MAC needs to be out of reset and proper clocks need to be configured.
* - DMA HW init need to be completed successfully, see osi_hw_dma_init
* - Mapping of physical IRQ line to DMA channel need to be maintained at
* OS Dependent layer and pass corresponding channel number.
*
* @note
* Traceability Details: TBD
*
* @note
* Classification:
* - Interrupt: Yes
* - Signal handler: Yes
* - Thread safe: No
* - Required Privileges: None
*
* @note
* API Group:
* - Initialization: Yes
* - Run time: Yes
* - De-initialization: No
*
* @retval 0 on success
* @retval -1 on failure.
*/
nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma,
nveu32_t chan, nveu32_t tx_rx, nveu32_t en_dis);
#ifndef OSI_STRIPPED_LIB
/**
* @brief - Read-validate HW registers for func safety.

View File

@@ -93,6 +93,10 @@ struct dma_local {
struct dma_chan_ops ops;
/** Flag to represent OSI DMA software init done */
unsigned int init_done;
/** Holds the MAC version of MAC controller */
nveu32_t mac_ver;
/** Represents whether DMA interrupts are VM or Non-VM */
nveu32_t vm_intr;
};
void eqos_init_dma_chan_ops(struct dma_chan_ops *ops);

View File

@@ -966,6 +966,8 @@ static void eqos_clear_vm_tx_intr(void *addr, nveu32_t chan)
(nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan));
osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX,
(nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan));
eqos_disable_chan_tx_intr(addr, chan);
}
/**
@@ -990,6 +992,8 @@ static void eqos_clear_vm_rx_intr(void *addr, nveu32_t chan)
(nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan));
osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX,
(nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan));
eqos_disable_chan_rx_intr(addr, chan);
}
/**

View File

@@ -23,6 +23,7 @@
#include "dma_local.h"
#include <local_common.h>
#include "hw_desc.h"
#include "../osi/common/common.h"
/**
* @brief g_dma - DMA local data variable
@@ -227,6 +228,19 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma)
return ret;
}
g_dma.mac_ver = osi_readl((unsigned char *)osi_dma->base + MAC_VERSION) &
MAC_VERSION_SNVER_MASK;
if (is_valid_mac_version(g_dma.mac_ver) == 0) {
OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID,
"Invalid MAC version\n", (nveu64_t)g_dma.mac_ver);
return -1;
}
if ((g_dma.mac_ver != OSI_EQOS_MAC_4_10) &&
(g_dma.mac_ver != OSI_EQOS_MAC_5_00)) {
g_dma.vm_intr = OSI_ENABLE;
}
/* Enable channel interrupts at wrapper level and start DMA */
for (i = 0; i < osi_dma->num_dma_chans; i++) {
chan = osi_dma->dma_chans[i];
@@ -371,6 +385,37 @@ nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma)
return ops_p->get_global_dma_status(osi_dma->base);
}
nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma,
nveu32_t chan,
nveu32_t tx_rx,
nveu32_t en_dis)
{
typedef void (*dma_intr_fn)(void *, nveu32_t);
dma_intr_fn fn[2][2][2] = {
{ { ops_p->disable_chan_tx_intr, ops_p->enable_chan_tx_intr },
{ ops_p->disable_chan_rx_intr, ops_p->enable_chan_rx_intr } },
{ { ops_p->clear_vm_tx_intr, ops_p->enable_chan_tx_intr },
{ ops_p->clear_vm_rx_intr, ops_p->enable_chan_rx_intr } }
};
if (validate_args(osi_dma) < 0) {
return -1;
}
if (validate_dma_chan_num(osi_dma, chan) < 0) {
return -1;
}
if ((tx_rx > OSI_DMA_CH_RX_INTR) ||
(en_dis > OSI_DMA_INTR_ENABLE)) {
return -1;
}
fn[g_dma.vm_intr][tx_rx][en_dis](osi_dma->base, chan);
return 0;
}
nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma,
nveu32_t chan)
{