nvethernetrm: eqos: TSN support for EQOS IP

1. Adds basic OSI API's for EST/FPE
2. EST/FPE support for EQOS
3. MMC counters for FPE
4. EST errors and state counter

Bug 200561100

Change-Id: Iee3e6caac5d16e1620c25420d72700f9cdd00465
Signed-off-by: rakesh goyal <rgoyal@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2319820
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Bhadram Varka <vbhadram@nvidia.com>
This commit is contained in:
rakesh goyal
2020-03-28 12:58:56 +05:30
committed by Bhadram Varka
parent 8f7983edb1
commit e18eedbdeb
9 changed files with 977 additions and 21 deletions

View File

@@ -527,6 +527,27 @@ struct osi_mmc_counters {
* segment that had checksum errors. This counter does not count * segment that had checksum errors. This counter does not count
* IP header bytes */ * IP header bytes */
nveu64_t mmc_rx_icmp_err_octets_h; nveu64_t mmc_rx_icmp_err_octets_h;
/** This counter provides the number of additional mPackets
* transmitted due to preemption */
unsigned long mmc_tx_fpe_frag_cnt;
/** This counter provides the count of number of times a hold
* request is given to MAC */
unsigned long mmc_tx_fpe_hold_req_cnt;
/** This counter provides the number of MAC frames with reassembly
* errors on the Receiver, due to mismatch in the fragment
* count value */
unsigned long mmc_rx_packet_reass_err_cnt;
/** This counter the number of received MAC frames rejected
* due to unknown SMD value and MAC frame fragments rejected due
* to arriving with an SMD-C when there was no preceding preempted
* frame */
unsigned long mmc_rx_packet_smd_err_cnt;
/** This counter provides the number of MAC frames that were
* successfully reassembled and delivered to MAC */
unsigned long mmc_rx_packet_asm_ok_cnt;
/** This counter provides the number of additional mPackets received
* due to preemption */
unsigned long mmc_rx_fpe_fragment_cnt;
}; };
/** /**

View File

@@ -129,6 +129,14 @@
#define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PAUSE_FRAMES_ENABLE 0U
#define OSI_PTP_REQ_CLK_FREQ 250000000U #define OSI_PTP_REQ_CLK_FREQ 250000000U
#define OSI_FLOW_CTRL_DISABLE 0U #define OSI_FLOW_CTRL_DISABLE 0U
#define OSI_MAX_24BITS 0xFFFFFFU
#define OSI_MAX_28BITS 0xFFFFFFFU
#define OSI_MAX_32BITS 0xFFFFFFFFU
#define OSI_GCL_SIZE_64 64U
#define OSI_GCL_SIZE_128 128U
#define OSI_GCL_SIZE_256 256U
#define OSI_GCL_SIZE_512 512U
#define OSI_GCL_SIZE_1024 1024U
#define OSI_POLL_COUNT 1000U #define OSI_POLL_COUNT 1000U
@@ -272,10 +280,6 @@
* @brief osi_update_stats_counter - update value by increment passed * @brief osi_update_stats_counter - update value by increment passed
* as parameter * as parameter
* *
* @note
* Algorithm:
* - Check for boundary and return sum
*
* @param[in] last_value: last value of stat counter * @param[in] last_value: last value of stat counter
* @param[in] incr: increment value * @param[in] incr: increment value
* *

View File

@@ -178,7 +178,7 @@ typedef my_lint_64 nvel64_t;
#define OSI_VLAN_ACTION_DEL 0x0U #define OSI_VLAN_ACTION_DEL 0x0U
#define OSI_RXQ_ROUTE_PTP 0U #define OSI_RXQ_ROUTE_PTP 0U
#define OSI_DELAY_1000US 1000U #define OSI_DELAY_1000US 1000U
#define OSI_DELAY_1US 1U
/** /**
* @addtogroup RSS related information * @addtogroup RSS related information
* *
@@ -619,6 +619,62 @@ struct osi_core_avb_algorithm {
}; };
#endif /* !OSI_STRIPPED_LIB */ #endif /* !OSI_STRIPPED_LIB */
/**
* @brief OSI Core EST structure
*/
struct osi_est_config {
/** enable/disable */
unsigned int en_dis;
/** 64 bit base time register
* if both vlaues are 0, take ptp time to avoid BTRE
* index 0 for nsec, index 1 for sec
*/
unsigned int btr[2];
/** 64 bit base time offset index 0 for nsec, index 1 for sec */
unsigned int btr_offset[2];
/** 40 bit cycle time register, index 0 for nsec, index 1 for sec */
unsigned int ctr[2];
/** Configured Time Interval width + 7 bit extension register */
unsigned int ter;
/** size of the gate control list */
unsigned int llr;
/** data array 8 bit gate op + 24 execution time
* MGBE HW support GCL depth 256 */
unsigned int gcl[OSI_GCL_SIZE_256];
};
/**
* @brief OSI Core FPE structure
*/
struct osi_fpe_config {
/** Queue Mask 1 preemption 0- express bit representation */
unsigned int tx_queue_preemption_enable;
/** RQ for all preemptable packets which are not filtered
* based on user priority or SA-DA
*/
unsigned int rq;
};
/**
* @brief OSI Core TSN error stats structure
*/
struct osi_tsn_stats {
/** Constant Gate Control Error */
unsigned long const_gate_ctr_err;
/** Head-Of-Line Blocking due to Scheduling */
unsigned long head_of_line_blk_sch;
/** Per TC Schedule Error */
unsigned long hlbs_q[OSI_MAX_TC_NUM];
/** Head-Of-Line Blocking due to Frame Size */
unsigned long head_of_line_blk_frm;
/** Per TC Frame Size Error */
unsigned long hlbf_q[OSI_MAX_TC_NUM];
/** BTR Error */
unsigned long base_time_reg_err;
/** Switch to Software Owned List Complete */
unsigned long sw_own_list_complete;
};
/** /**
* @brief PTP configuration structure * @brief PTP configuration structure
*/ */
@@ -737,6 +793,10 @@ struct osi_core_priv_data {
nveu32_t rxq_ctrl[OSI_MGBE_MAX_NUM_CHANS]; nveu32_t rxq_ctrl[OSI_MGBE_MAX_NUM_CHANS];
/** Rx MTl Queue mapping based on User Priority field */ /** Rx MTl Queue mapping based on User Priority field */
nveu32_t rxq_prio[OSI_MGBE_MAX_NUM_CHANS]; nveu32_t rxq_prio[OSI_MGBE_MAX_NUM_CHANS];
/** TQ:TC mapping */
unsigned int tc[OSI_MGBE_MAX_NUM_CHANS];
/** Residual queue valid with FPE support */
unsigned int residual_queue;
/** MAC HW type EQOS based on DT compatible */ /** MAC HW type EQOS based on DT compatible */
nveu32_t mac; nveu32_t mac;
/** MAC version */ /** MAC version */
@@ -786,6 +846,16 @@ struct osi_core_priv_data {
unsigned short vlan_filter_cnt; unsigned short vlan_filter_cnt;
/** RSS core structure */ /** RSS core structure */
struct osi_core_rss rss; struct osi_core_rss rss;
/** HW supported feature list */
struct osi_hw_features *hw_feature;
/** Switch to Software Owned List Complete.
* 1 - Successful and User configured GCL in placed */
unsigned int est_ready;
/** FPE enabled, verify and respose done with peer device
* 1- Sucessful and can be used between P2P device */
unsigned int fpe_ready;
/** TSN stats counters */
struct osi_tsn_stats tsn_stats;
}; };
/** /**
@@ -2237,4 +2307,49 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core,
* @retval -1 on failure. * @retval -1 on failure.
*/ */
nve32_t osi_config_rss(struct osi_core_priv_data *const osi_core); nve32_t osi_config_rss(struct osi_core_priv_data *const osi_core);
/**
* @brief osi_hw_config_est - Read Setting for GCL from input and update
* registers.
*
* Algorithm:
* 1) Write TER, LLR and EST control register
* 2) Update GCL to sw own GCL (MTL_EST_Status bit SWOL will tell which is
* owned by SW) and store which GCL is in use currently in sw.
* 3) TODO set DBGB and DBGM for debugging
* 4) EST_data and GCRR to 1, update entry sno in ADDR and put data at
* est_gcl_data enable GCL MTL_EST_SSWL and wait for self clear or use
* SWLC in MTL_EST_Status. Please note new GCL will be pushed for each entry.
* 5) Configure btr. Update btr based on current time (current time
* should be updated based on PTP by this time)
*
* @param[in] osi_core: OSI core private data structure.
* @param[in] est: Configuration osi_est_config structure.
*
* @note MAC should be init and started. see osi_start_mac()
*
* @retval 0 on success
* @retval -1 on failure.
*/
int osi_hw_config_est(struct osi_core_priv_data *osi_core,
struct osi_est_config *est);
/**
* @brief osi_hw_config_fep - Read Setting for preemption and express for TC
* and update registers.
*
* Algorithm:
* 1) Check for TC enable and TC has masked for setting to preemptable.
* 2) update FPE control status register
*
* @param[in] osi_core: OSI core private data structure.
* @param[in] fpe: Configuration osi_fpe_config structure.
*
* @note MAC should be init and started. see osi_start_mac()
*
* @retval 0 on success
* @retval -1 on failure.
*/
int osi_hw_config_fpe(struct osi_core_priv_data *osi_core,
struct osi_fpe_config *fpe);
#endif /* INCLUDED_OSI_CORE_H */ #endif /* INCLUDED_OSI_CORE_H */

View File

@@ -204,6 +204,12 @@ struct core_ops {
struct osi_hw_features *hw_feat); struct osi_hw_features *hw_feat);
/** Called to configure RSS for MAC */ /** Called to configure RSS for MAC */
nve32_t (*config_rss)(struct osi_core_priv_data *osi_core); nve32_t (*config_rss)(struct osi_core_priv_data *osi_core);
/** Called to update GCL config */
int (*hw_config_est)(struct osi_core_priv_data *const osi_core,
struct osi_est_config *const est);
/** Called to update FPE config */
int (*hw_config_fpe)(struct osi_core_priv_data *const osi_core,
struct osi_fpe_config *const fpe);
}; };

View File

@@ -21,6 +21,7 @@
*/ */
#include "../osi/common/common.h" #include "../osi/common/common.h"
#include <local_common.h>
#include <osi_core.h> #include <osi_core.h>
#include "eqos_core.h" #include "eqos_core.h"
#include "eqos_mmc.h" #include "eqos_mmc.h"
@@ -1399,6 +1400,135 @@ static void eqos_configure_dma(struct osi_core_priv_data *const osi_core)
osi_writela(osi_core, value, (nveu8_t *)base + EQOS_DMA_BMR); osi_writela(osi_core, value, (nveu8_t *)base + EQOS_DMA_BMR);
} }
/**
* @brief eqos_enable_mtl_interrupts - Enable MTL interrupts
*
* Algorithm: enable MTL interrupts for EST
*
* @param[in] addr: MAC base IOVA address.
*
* @note MAC should be init and started. see osi_start_mac()
*/
static inline void eqos_enable_mtl_interrupts(void *addr)
{
unsigned int mtl_est_ir = OSI_DISABLE;
mtl_est_ir = osi_readl((unsigned char *)addr + EQOS_MTL_EST_ITRE);
/* enable only MTL interrupt realted to
* Constant Gate Control Error
* Head-Of-Line Blocking due to Scheduling
* Head-Of-Line Blocking due to Frame Size
* BTR Error
* Switch to S/W owned list Complete
*/
mtl_est_ir |= (EQOS_MTL_EST_ITRE_CGCE | EQOS_MTL_EST_ITRE_IEHS |
EQOS_MTL_EST_ITRE_IEHF | EQOS_MTL_EST_ITRE_IEBE |
EQOS_MTL_EST_ITRE_IECC);
osi_writel(mtl_est_ir, (unsigned char *)addr + EQOS_MTL_EST_ITRE);
}
/**
* @brief eqos_enable_fpe_interrupts - Enable MTL interrupts
*
* Algorithm: enable FPE interrupts
*
* @param[in] addr: MAC base IOVA address.
*
* @note MAC should be init and started. see osi_start_mac()
*/
static inline void eqos_enable_fpe_interrupts(void *addr)
{
unsigned int value = OSI_DISABLE;
/* Read MAC IER Register and enable Frame Preemption Interrupt
* Enable */
value = osi_readl((unsigned char *)addr + EQOS_MAC_IMR);
value |= EQOS_IMR_FPEIE;
osi_writel(value, (unsigned char *)addr + EQOS_MAC_IMR);
}
/**
* @brief eqos_tsn_init - initialize TSN feature
*
* Algorithm:
* 1) If hardware support EST,
* a) Set default EST configuration
* b) Set enable interrupts
* 2) If hardware supports FPE
* a) Set default FPE configuration
* b) enable interrupts
*
* @param[in] osi_core: OSI core private data structure.
* @param[in] est_sel: EST HW support present or not
* @param[in] fpe_sel: FPE HW support present or not
*
* @note MAC should be init and started. see osi_start_mac()
*/
static void eqos_tsn_init(struct osi_core_priv_data *osi_core,
unsigned int est_sel, unsigned int fpe_sel)
{
unsigned int val = 0x0;
unsigned int temp = 0U;
if (est_sel == OSI_ENABLE) {
val = osi_readl((unsigned char *)osi_core->base +
EQOS_MTL_EST_CONTROL);
/*
* PTOV PTP clock period * 6
* dual-port RAM based asynchronous FIFO controllers or
* Single-port RAM based synchronous FIFO controllers
* CTOV 96 x Tx clock period
* :
* :
* set other default value
*/
val &= ~EQOS_MTL_EST_CONTROL_PTOV;
if (osi_core->pre_si == OSI_ENABLE) {
/* 6*1/(78.6 MHz) in ns*/
temp = (6U * 13U);
} else {
/* 6*1/(312 MHz) in ns*/
temp = (6U * 3U);
}
temp = temp << EQOS_MTL_EST_CONTROL_PTOV_SHIFT;
val |= temp;
/* We have a bug on CTOV for Qbv that synopsys is yet to
* fix[Case 8001147927, Bug 200468714]. You can go ahead
* with 128*8ns for now. TODO */
val &= ~EQOS_MTL_EST_CONTROL_CTOV;
temp = (128U * 8U);
temp = temp << EQOS_MTL_EST_CONTROL_CTOV_SHIFT;
val |= temp;
/*Loop Count to report Scheduling Error*/
val &= ~EQOS_MTL_EST_CONTROL_LCSE;
val |= EQOS_MTL_EST_CONTROL_LCSE_VAL;
osi_writel(val, (unsigned char *)osi_core->base +
EQOS_MTL_EST_CONTROL);
eqos_enable_mtl_interrupts(osi_core->base);
}
if (fpe_sel == OSI_ENABLE) {
val = osi_readl((unsigned char *)osi_core->base +
EQOS_MAC_RQC1R);
val &= ~EQOS_MAC_RQC1R_FPRQ;
temp = osi_core->residual_queue;
temp = temp << EQOS_MAC_RQC1R_FPRQ_SHIFT;
temp = (temp & EQOS_MAC_RQC1R_FPRQ);
val |= temp;
osi_writel(val, (unsigned char *)osi_core->base +
EQOS_MAC_RQC1R);
eqos_enable_fpe_interrupts(osi_core->base);
}
/* CBS setting for TC should be by user application/IOCTL as
* per requirement */
}
/** /**
* @brief eqos_core_init - EQOS MAC, MTL and common DMA Initialization * @brief eqos_core_init - EQOS MAC, MTL and common DMA Initialization
* *
@@ -1509,12 +1639,69 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core,
/* configure EQOS DMA */ /* configure EQOS DMA */
eqos_configure_dma(osi_core); eqos_configure_dma(osi_core);
/* tsn initialization */
if (osi_core->hw_feature != OSI_NULL) {
eqos_tsn_init(osi_core, osi_core->hw_feature->est_sel,
osi_core->hw_feature->fpe_sel);
}
/* initialize L3L4 Filters variable */ /* initialize L3L4 Filters variable */
osi_core->l3l4_filter_bitmask = OSI_NONE; osi_core->l3l4_filter_bitmask = OSI_NONE;
return ret; return ret;
} }
/**
* @brief eqos_handle_mac_fpe_intrs
*
* Algorithm: This function takes care of handling the
* MAC FPE interrupts.
*
* @param[in] osi_core: OSI core private data structure.
*
* @note MAC interrupts need to be enabled
*/
static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core)
{
unsigned int val = 0;
/* interrupt bit clear on read as CSR_SW is reset */
val = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS);
if ((val & EQOS_MAC_FPE_CTS_RVER) == EQOS_MAC_FPE_CTS_RVER) {
val &= ~EQOS_MAC_FPE_CTS_RVER;
val |= EQOS_MAC_FPE_CTS_SRSP;
}
if ((val & EQOS_MAC_FPE_CTS_RRSP) == EQOS_MAC_FPE_CTS_RRSP) {
/* received respose packet Nothing to be done, it means other
* IP also support FPE
*/
val &= ~EQOS_MAC_FPE_CTS_RRSP;
val &= ~EQOS_MAC_FPE_CTS_TVER;
osi_core->fpe_ready = OSI_ENABLE;
val |= EQOS_MAC_FPE_CTS_EFPE;
}
if ((val & EQOS_MAC_FPE_CTS_TRSP) == EQOS_MAC_FPE_CTS_TRSP) {
/* TX response packet sucessful */
osi_core->fpe_ready = OSI_ENABLE;
/* Enable frame preemption */
val &= ~EQOS_MAC_FPE_CTS_TRSP;
val &= ~EQOS_MAC_FPE_CTS_TVER;
val |= EQOS_MAC_FPE_CTS_EFPE;
}
if ((val & EQOS_MAC_FPE_CTS_TVER) == EQOS_MAC_FPE_CTS_TVER) {
/*Transmit verif packet sucessful*/
osi_core->fpe_ready = OSI_DISABLE;
val &= ~EQOS_MAC_FPE_CTS_TVER;
val &= ~EQOS_MAC_FPE_CTS_EFPE;
}
osi_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS);
}
/** /**
* @brief eqos_handle_mac_intrs - Handle MAC interrupts * @brief eqos_handle_mac_intrs - Handle MAC interrupts
* *
@@ -1554,8 +1741,10 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core,
mac_imr = osi_readla(osi_core, mac_imr = osi_readla(osi_core,
(nveu8_t *)osi_core->base + EQOS_MAC_IMR); (nveu8_t *)osi_core->base + EQOS_MAC_IMR);
mac_isr = (mac_isr & mac_imr); mac_isr = (mac_isr & mac_imr);
/* RGMII/SMII interrupt */ /* RGMII/SMII interrupt */
if ((mac_isr & EQOS_MAC_ISR_RGSMIIS) != EQOS_MAC_ISR_RGSMIIS) { if (((mac_isr & EQOS_MAC_ISR_RGSMIIS) != EQOS_MAC_ISR_RGSMIIS) &&
((mac_isr & EQOS_MAC_IMR_FPEIS) != EQOS_MAC_IMR_FPEIS)) {
return; return;
} }
@@ -1595,6 +1784,12 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core,
} else { } else {
/* Nothing here */ /* Nothing here */
} }
if (((mac_isr & EQOS_MAC_IMR_FPEIS) == EQOS_MAC_IMR_FPEIS) &&
((mac_imr & EQOS_IMR_FPEIE) == EQOS_IMR_FPEIE)) {
eqos_handle_mac_fpe_intrs(osi_core);
mac_isr &= ~EQOS_MAC_IMR_FPEIS;
}
osi_writel(mac_isr, (unsigned char *)osi_core->base + EQOS_MAC_ISR);
} }
/** /**
@@ -1652,6 +1847,111 @@ static inline void update_dma_sr_stats(
} }
} }
/**
* @brief eqos_handle_mtl_intrs - Handle MTL interrupts
*
* Algorithm: Code to handle interrupt for MTL EST error and status.
* There are possible 4 errors which can be part of common interrupt in case of
* MTL_EST_SCH_ERR (sheduling error)- HLBS
* MTL_EST_FRMS_ERR (Frame size error) - HLBF
* MTL_EST_FRMC_ERR (frame check error) - HLBF
* Constant Gate Control Error - when time interval in less
* than or equal to cycle time, llr = 1
* There is one status interrupt which says swich to SWOL complete.
*
* @param[in] osi_core: osi core priv data structure
*
* @note MAC should be init and started. see osi_start_mac()
*/
static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core)
{
unsigned int val = 0;
unsigned int sch_err = 0;
unsigned int frm_err = 0;
unsigned int temp = 0U;
unsigned int i = 0;
unsigned long stat_val = 0;
val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_EST_STATUS);
val &= (EQOS_MTL_EST_STATUS_CGCE | EQOS_MTL_EST_STATUS_HLBS |
EQOS_MTL_EST_STATUS_HLBF | EQOS_MTL_EST_STATUS_BTRE |
EQOS_MTL_EST_STATUS_SWLC);
/* return if interrupt is not related to EST */
if (val == OSI_DISABLE) {
return;
}
/* increase counter write 1 back will clear */
if ((val & EQOS_MTL_EST_STATUS_CGCE) == EQOS_MTL_EST_STATUS_CGCE) {
osi_core->est_ready = OSI_DISABLE;
stat_val = osi_core->tsn_stats.const_gate_ctr_err;
osi_core->tsn_stats.const_gate_ctr_err =
osi_update_stats_counter(stat_val, 1U);
}
if ((val & EQOS_MTL_EST_STATUS_HLBS) == EQOS_MTL_EST_STATUS_HLBS) {
osi_core->est_ready = OSI_DISABLE;
stat_val = osi_core->tsn_stats.head_of_line_blk_sch;
osi_core->tsn_stats.head_of_line_blk_sch =
osi_update_stats_counter(stat_val, 1U);
/* Need to read MTL_EST_Sch_Error register and cleared */
sch_err = osi_readl(osi_core->base + EQOS_MTL_EST_SCH_ERR);
for (i = 0U; i < OSI_MAX_TC_NUM; i++) {
temp = OSI_ENABLE;
temp = temp << i;
if ((sch_err & temp) == temp) {
stat_val = osi_core->tsn_stats.hlbs_q[i];
osi_core->tsn_stats.hlbs_q[i] =
osi_update_stats_counter(stat_val, 1U);
}
}
sch_err &= 0xFFU; /* only 8 TC allowed so clearing all */
osi_writel(sch_err, osi_core->base + EQOS_MTL_EST_SCH_ERR);
}
if ((val & EQOS_MTL_EST_STATUS_HLBF) == EQOS_MTL_EST_STATUS_HLBF) {
osi_core->est_ready = OSI_DISABLE;
stat_val = osi_core->tsn_stats.head_of_line_blk_frm;
osi_core->tsn_stats.head_of_line_blk_frm =
osi_update_stats_counter(stat_val, 1U);
/* Need to read MTL_EST_Frm_Size_Error register and cleared */
frm_err = osi_readl(osi_core->base + EQOS_MTL_EST_FRMS_ERR);
for (i = 0U; i < OSI_MAX_TC_NUM; i++) {
temp = OSI_ENABLE;
temp = temp << i;
if ((frm_err & temp) == temp) {
stat_val = osi_core->tsn_stats.hlbf_q[i];
osi_core->tsn_stats.hlbf_q[i] =
osi_update_stats_counter(stat_val, 1U);
}
}
frm_err &= 0xFFU; /* 8 TC allowed so clearing all */
osi_writel(frm_err, osi_core->base + EQOS_MTL_EST_FRMS_ERR);
}
if ((val & EQOS_MTL_EST_STATUS_SWLC) == EQOS_MTL_EST_STATUS_SWLC) {
if ((val & EQOS_MTL_EST_STATUS_BTRE) !=
EQOS_MTL_EST_STATUS_BTRE) {
osi_core->est_ready = OSI_ENABLE;
}
stat_val = osi_core->tsn_stats.sw_own_list_complete;
osi_core->tsn_stats.sw_own_list_complete =
osi_update_stats_counter(stat_val, 1U);
}
if ((val & EQOS_MTL_EST_STATUS_BTRE) == EQOS_MTL_EST_STATUS_BTRE) {
osi_core->est_ready = OSI_DISABLE;
stat_val = osi_core->tsn_stats.base_time_reg_err;
osi_core->tsn_stats.base_time_reg_err =
osi_update_stats_counter(stat_val, 1U);
osi_core->est_ready = OSI_DISABLE;
}
/* clear EST status register as interrupt is handled */
osi_writel(val, osi_core->base + EQOS_MTL_EST_STATUS);
}
/** /**
* @brief eqos_handle_common_intr - Handles common interrupt. * @brief eqos_handle_common_intr - Handles common interrupt.
* *
@@ -1677,6 +1977,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core)
nveu32_t i = 0; nveu32_t i = 0;
nveu32_t dma_sr = 0; nveu32_t dma_sr = 0;
nveu32_t dma_ier = 0; nveu32_t dma_ier = 0;
unsigned int mtl_isr = 0;
dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR); dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR);
if (dma_isr == 0U) { if (dma_isr == 0U) {
@@ -1719,6 +2020,15 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core)
} }
eqos_handle_mac_intrs(osi_core, dma_isr); eqos_handle_mac_intrs(osi_core, dma_isr);
/* Handle MTL inerrupts */
mtl_isr = osi_readl((unsigned char *)base + EQOS_MTL_INTR_STATUS);
if (((mtl_isr & EQOS_MTL_IS_ESTIS) == EQOS_MTL_IS_ESTIS) &&
((dma_isr & EQOS_DMA_ISR_MTLIS) == EQOS_DMA_ISR_MTLIS)) {
eqos_handle_mtl_intrs(osi_core);
mtl_isr &= ~EQOS_MTL_IS_ESTIS;
osi_writel(mtl_isr, (unsigned char *)base +
EQOS_MTL_INTR_STATUS);
}
} }
/** /**
@@ -3218,6 +3528,335 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core)
eqos_stop_mac(osi_core); eqos_stop_mac(osi_core);
} }
/**
* @brief eqos_hw_est_write - indirect write the GCL to Software own list
* (SWOL)
*
* @param[in] base: MAC base IOVA address.
* @param[in] addr_val: Address offset for indirect write.
* @param[in] data: Data to be written at offset.
* @param[in] gcla: Gate Control List Address, 0 for ETS register.
* 1 for GCL memory.
*
* @note MAC should be init and started. see osi_start_mac()
*
* @retval 0 on success
* @retval -1 on failure.
*/
static int eqos_hw_est_write(struct osi_core_priv_data *osi_core,
unsigned int addr_val,
unsigned int data, unsigned int gcla)
{
void *base = osi_core->base;
int retry = 1000;
unsigned int val = 0x0;
osi_writel(data, (unsigned char *)base + EQOS_MTL_EST_DATA);
val &= ~EQOS_MTL_EST_ADDR_MASK;
val |= (gcla == 1U) ? 0x0U : EQOS_MTL_EST_GCRR;
val |= EQOS_MTL_EST_SRWO;
val |= addr_val;
osi_writel(val, (unsigned char *)base + EQOS_MTL_EST_GCL_CONTROL);
while (--retry > 0) {
osi_core->osd_ops.udelay(OSI_DELAY_1US);
val = osi_readl((unsigned char *)base +
EQOS_MTL_EST_GCL_CONTROL);
if ((val & EQOS_MTL_EST_SRWO) == EQOS_MTL_EST_SRWO) {
continue;
}
break;
}
if (((val & EQOS_MTL_EST_ERR0) == EQOS_MTL_EST_ERR0) ||
(retry <= 0)) {
return -1;
}
return 0;
}
/**
* @brief eqos_gcl_validate - validate GCL from user
*
* Algorithm: validate GCL size and width of time interval value
*
* @param[in] osi_core: OSI core private data structure.
* @param[in] est: Configuration input argument.
*
* @note MAC should be init and started. see osi_start_mac()
*
* @retval 0 on success
* @retval -1 on failure.
*/
static inline int eqos_gcl_validate(struct osi_core_priv_data *osi_core,
struct osi_est_config *est)
{
unsigned int wid_val = 0x0U;
unsigned int dep = 0x0U;
unsigned int i;
if (osi_core->hw_feature == OSI_NULL) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
"HW feature is NULL\n", 0ULL);
return -1;
}
if (osi_core->hw_feature->gcl_width == 0x1U) {
wid_val = OSI_MAX_24BITS;
} else if (osi_core->hw_feature->gcl_width == 0x2U) {
wid_val = OSI_MAX_28BITS;
} else if (osi_core->hw_feature->gcl_width == 0x3U) {
wid_val = OSI_MAX_32BITS;
} else {
/* Do Nothing */
}
if (osi_core->hw_feature->gcl_depth == 0x1U) {
dep = OSI_GCL_SIZE_64;
} else if (osi_core->hw_feature->gcl_depth == 0x2U) {
dep = OSI_GCL_SIZE_128;
} else if (osi_core->hw_feature->gcl_depth == 0x3U) {
dep = OSI_GCL_SIZE_256;
} else if (osi_core->hw_feature->gcl_depth == 0x4U) {
dep = OSI_GCL_SIZE_512;
} else if (osi_core->hw_feature->gcl_depth == 0x5U) {
dep = OSI_GCL_SIZE_1024;
} else {
/* Do Nothing */
}
if (est->llr > dep) {
return -1;
}
for (i = 0U; i < est->llr; i++) {
if (est->gcl[i] <= wid_val) {
continue;
}
return -1;
}
return 0;
}
/**
* @brief eqos_hw_config_est - Read Setting for GCL from input and update
* registers.
*
* Algorithm:
* 1) Write TER, LLR and EST control register
* 2) Update GCL to sw own GCL (MTL_EST_Status bit SWOL will tell which is
* owned by SW) and store which GCL is in use currently in sw.
* 3) TODO set DBGB and DBGM for debugging
* 4) EST_data and GCRR to 1, update entry sno in ADDR and put data at
* est_gcl_data enable GCL MTL_EST_SSWL and wait for self clear or use
* SWLC in MTL_EST_Status. Please note new GCL will be pushed for each entry.
* 5) Configure btr. Update btr based on current time (current time
* should be updated based on PTP by this time)
*
* @param[in] osi_core: OSI core private data structure.
* @param[in] est: EST configuration input argument.
*
* @note MAC should be init and started. see osi_start_mac()
*
* @retval 0 on success
* @retval -1 on failure.
*/
static int eqos_hw_config_est(struct osi_core_priv_data *osi_core,
struct osi_est_config *est)
{
void *base = osi_core->base;
unsigned int btr[2] = {0};
unsigned int val = 0x0;
unsigned int addr = 0x0;
unsigned int i;
int ret = 0;
if ((osi_core->hw_feature != OSI_NULL) &&
(osi_core->hw_feature->est_sel == OSI_DISABLE)) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
"EST not supported in HW\n", 0ULL);
return -1;
}
if (est->en_dis == OSI_DISABLE) {
val = osi_readl((unsigned char *)base + EQOS_MTL_EST_CONTROL);
val &= ~EQOS_MTL_EST_EEST;
osi_writel(val, (unsigned char *)base + EQOS_MTL_EST_CONTROL);
return 0;
}
if (eqos_gcl_validate(osi_core, est) < 0) {
return -1;
}
ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_CTR_LOW, est->ctr[0],
OSI_DISABLE);
if (ret < 0) {
return ret;
}
/* check for est->ctr[i] not more than FF, TODO as per hw config
* parameter we can have max 0x3 as this value in sec */
est->ctr[1] &= EQOS_MTL_EST_CTR_HIGH_MAX;
ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_CTR_HIGH, est->ctr[1],
OSI_DISABLE);
if (ret < 0) {
return ret;
}
ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_TER, est->ter, OSI_DISABLE);
if (ret < 0) {
return ret;
}
ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_LLR, est->llr, OSI_DISABLE);
if (ret < 0) {
return ret;
}
/* Write GCL table */
for (i = 0U; i < est->llr; i++) {
addr = i;
addr = addr << EQOS_MTL_EST_ADDR_SHIFT;
addr &= EQOS_MTL_EST_ADDR_MASK;
ret = eqos_hw_est_write(osi_core, addr, est->gcl[i], OSI_ENABLE);
if (ret < 0) {
return ret;
}
}
if (est->btr[0] == 0U && est->btr[1] == 0U) {
common_get_systime_from_mac(osi_core->base, osi_core->mac,
&btr[1], &btr[0]);
}
/* Write parameters */
ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_BTR_LOW,
btr[0] + est->btr_offset[0], OSI_DISABLE);
if (ret < 0) {
return ret;
}
ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_BTR_HIGH,
btr[1] + est->btr_offset[1], OSI_DISABLE);
if (ret < 0) {
return ret;
}
val = osi_readl((unsigned char *)base + EQOS_MTL_EST_CONTROL);
/* Store table */
val |= EQOS_MTL_EST_SSWL;
val |= EQOS_MTL_EST_EEST;
osi_writel(val, (unsigned char *)base + EQOS_MTL_EST_CONTROL);
return ret;
}
/**
* @brief eqos_hw_config_fep - Read Setting for preemption and express for TC
* and update registers.
*
* Algorithm:
* 1) Check for TC enable and TC has masked for setting to preemptable.
* 2) update FPE control status register
*
* @param[in] osi_core: OSI core private data structure.
* @param[in] fpe: FPE configuration input argument.
*
* @note MAC should be init and started. see osi_start_mac()
*
* @retval 0 on success
* @retval -1 on failure.
*/
static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core,
struct osi_fpe_config *fpe)
{
unsigned int i = 0U;
unsigned int val = 0U;
unsigned int temp = 0U, temp1 = 0U;
unsigned int temp_shift = 0U;
if ((osi_core->hw_feature != OSI_NULL) &&
(osi_core->hw_feature->fpe_sel == OSI_DISABLE)) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
"FPE not supported in HW\n", 0ULL);
return -1;
}
osi_core->fpe_ready = OSI_DISABLE;
val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS);
if (((fpe->tx_queue_preemption_enable << EQOS_MTL_FPE_CTS_PEC_SHIFT) &
EQOS_MTL_FPE_CTS_PEC) == OSI_DISABLE) {
val &= ~EQOS_MAC_FPE_CTS_EFPE;
osi_writel(val, (unsigned char *)osi_core->base +
EQOS_MAC_FPE_CTS);
val = osi_readl((unsigned char *)osi_core->base +
EQOS_MAC_RQC1R);
val &= ~EQOS_MAC_RQC1R_FPRQ;
osi_writel(val, (unsigned char *)osi_core->base +
EQOS_MAC_RQC1R);
return 0;
}
val &= ~EQOS_MTL_FPE_CTS_PEC;
for (i = 0U; i < OSI_MAX_TC_NUM; i++) {
/* max 8 bit for this structure fot TC/TXQ. Set the TC for express or
* preemption. Default is express for a TC. DWCXG_NUM_TC = 8 */
temp = OSI_BIT(i);
if ((fpe->tx_queue_preemption_enable & temp) == temp) {
temp_shift = i;
temp_shift += EQOS_MTL_FPE_CTS_PEC_SHIFT;
/* set queue for preemtable */
if (temp_shift < EQOS_MTL_FPE_CTS_PEC_MAX_SHIFT) {
temp1 = OSI_ENABLE;
temp1 = temp1 << temp_shift;
val |= temp1;
} else {
/* Do nothing */
}
}
}
osi_writel(val, (unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS);
/* Setting RQ as RxQ 0 is not allowed */
if (fpe->rq == 0x0U || fpe->rq >= OSI_EQOS_MAX_NUM_CHANS) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
"EST init failed due to wrong RQ\n", fpe->rq);
return -1;
}
val = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC1R);
val &= ~EQOS_MAC_RQC1R_FPRQ;
temp = fpe->rq;
temp = temp << EQOS_MAC_RQC1R_FPRQ_SHIFT;
temp = (temp & EQOS_MAC_RQC1R_FPRQ);
val |= temp;
/* update RQ in OSI CORE struct */
osi_core->residual_queue = fpe->rq;
osi_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R);
/* initiate SVER for SMD-V and SMD-R */
val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS);
val |= EQOS_MAC_FPE_CTS_SVER;
osi_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS);
val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV);
val &= ~EQOS_MTL_FPE_ADV_HADV_MASK;
/* (minimum_fragment_size +IPG/EIPG + Preamble) *.8 ~98ns for10G */
val |= EQOS_MTL_FPE_ADV_HADV_VAL;
osi_writel(val, (unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV);
return 0;
}
/** /**
* @brief poll_for_mii_idle Query the status of an ongoing DMA transfer * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer
* *
@@ -4515,4 +5154,6 @@ void eqos_init_core_ops(struct core_ops *ops)
ops->set_mdc_clk_rate = eqos_set_mdc_clk_rate; ops->set_mdc_clk_rate = eqos_set_mdc_clk_rate;
ops->config_mac_loopback = eqos_config_mac_loopback; ops->config_mac_loopback = eqos_config_mac_loopback;
#endif /* !OSI_STRIPPED_LIB */ #endif /* !OSI_STRIPPED_LIB */
ops->hw_config_est = eqos_hw_config_est;
ops->hw_config_fpe = eqos_hw_config_fpe;
} }

View File

@@ -100,6 +100,8 @@
#define EQOS_MAC_MDIO_ADDRESS 0x0200 #define EQOS_MAC_MDIO_ADDRESS 0x0200
#define EQOS_MAC_MDIO_DATA 0x0204 #define EQOS_MAC_MDIO_DATA 0x0204
#define EQOS_5_00_MAC_ARPPA 0x0210 #define EQOS_5_00_MAC_ARPPA 0x0210
#define EQOS_MAC_CSR_SW_CTL 0x0230
#define EQOS_MAC_FPE_CTS 0x0234
#define EQOS_MAC_MA0HR 0x0300 #define EQOS_MAC_MA0HR 0x0300
#define EQOS_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) #define EQOS_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U)
#define EQOS_MAC_MA0LR 0x0304 #define EQOS_MAC_MA0LR 0x0304
@@ -134,7 +136,18 @@
* @{ * @{
*/ */
#define EQOS_MTL_OP_MODE 0x0C00 #define EQOS_MTL_OP_MODE 0x0C00
#define EQOS_MTL_INTR_STATUS 0x0C20
#define EQOS_MTL_RXQ_DMA_MAP0 0x0C30 #define EQOS_MTL_RXQ_DMA_MAP0 0x0C30
#define EQOS_MTL_EST_CONTROL 0x0C50
#define EQOS_MTL_EST_STATUS 0x0C58
#define EQOS_MTL_EST_SCH_ERR 0x0C60
#define EQOS_MTL_EST_FRMS_ERR 0x0C64
#define EQOS_MTL_EST_FRMC_ERR 0x0C68
#define EQOS_MTL_EST_ITRE 0x0C70
#define EQOS_MTL_EST_GCL_CONTROL 0x0C80
#define EQOS_MTL_EST_DATA 0x0C84
#define EQOS_MTL_FPE_CTS 0x0C90
#define EQOS_MTL_FPE_ADV 0x0C94
#define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) #define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U)
#define EQOS_MTL_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) #define EQOS_MTL_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U)
#define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) #define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U)
@@ -194,6 +207,11 @@
#define EQOS_MCR_CST OSI_BIT(21) #define EQOS_MCR_CST OSI_BIT(21)
#define EQOS_MCR_GPSLCE OSI_BIT(23) #define EQOS_MCR_GPSLCE OSI_BIT(23)
#define EQOS_IMR_RGSMIIIE OSI_BIT(0) #define EQOS_IMR_RGSMIIIE OSI_BIT(0)
#define EQOS_IMR_PCSLCHGIE OSI_BIT(1)
#define EQOS_IMR_PCSANCIE OSI_BIT(2)
#define EQOS_IMR_PMTIE OSI_BIT(4)
#define EQOS_IMR_LPIIE OSI_BIT(5)
#define EQOS_IMR_FPEIE OSI_BIT(17)
#define EQOS_MAC_PCS_LNKSTS OSI_BIT(19) #define EQOS_MAC_PCS_LNKSTS OSI_BIT(19)
#define EQOS_MAC_PCS_LNKMOD OSI_BIT(16) #define EQOS_MAC_PCS_LNKMOD OSI_BIT(16)
#define EQOS_MAC_PCS_LNKSPEED (OSI_BIT(17) | OSI_BIT(18)) #define EQOS_MAC_PCS_LNKSPEED (OSI_BIT(17) | OSI_BIT(18))
@@ -213,9 +231,14 @@
#define EQOS_DMA_BMR_DPSW OSI_BIT(8) #define EQOS_DMA_BMR_DPSW OSI_BIT(8)
#define EQOS_MAC_RQC1R_MCBCQ1 OSI_BIT(16) #define EQOS_MAC_RQC1R_MCBCQ1 OSI_BIT(16)
#define EQOS_MAC_RQC1R_MCBCQEN OSI_BIT(20) #define EQOS_MAC_RQC1R_MCBCQEN OSI_BIT(20)
#define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(24) | OSI_BIT(26) | \
OSI_BIT(27))
#define EQOS_MAC_RQC1R_FPRQ_SHIFT 24U
#define EQOS_MTL_QTOMR_FTQ_LPOS OSI_BIT(0) #define EQOS_MTL_QTOMR_FTQ_LPOS OSI_BIT(0)
#define EQOS_DMA_ISR_MTLIS OSI_BIT(16)
#define EQOS_DMA_ISR_MACIS OSI_BIT(17) #define EQOS_DMA_ISR_MACIS OSI_BIT(17)
#define EQOS_MAC_ISR_RGSMIIS OSI_BIT(0) #define EQOS_MAC_ISR_RGSMIIS OSI_BIT(0)
#define EQOS_MAC_IMR_FPEIS OSI_BIT(17)
#define EQOS_MTL_TXQ_QW_ISCQW OSI_BIT(4) #define EQOS_MTL_TXQ_QW_ISCQW OSI_BIT(4)
#define EQOS_DMA_SBUS_RD_OSR_LMT 0x001F0000U #define EQOS_DMA_SBUS_RD_OSR_LMT 0x001F0000U
#define EQOS_DMA_SBUS_WR_OSR_LMT 0x1F000000U #define EQOS_DMA_SBUS_WR_OSR_LMT 0x1F000000U
@@ -408,6 +431,89 @@
(TEGRA_SID_EQOS_CH5) |\ (TEGRA_SID_EQOS_CH5) |\
(TEGRA_SID_EQOS)) (TEGRA_SID_EQOS))
#define EQOS_MMC_INTR_DISABLE 0xFFFFFFFFU #define EQOS_MMC_INTR_DISABLE 0xFFFFFFFFU
/* MAC FPE control/statusOSI_BITmap */
#define EQOS_MAC_FPE_CTS_EFPE OSI_BIT(0)
#define EQOS_MAC_FPE_CTS_TRSP OSI_BIT(19)
#define EQOS_MAC_FPE_CTS_TVER OSI_BIT(18)
#define EQOS_MAC_FPE_CTS_RRSP OSI_BIT(17)
#define EQOS_MAC_FPE_CTS_RVER OSI_BIT(16)
#define EQOS_MAC_FPE_CTS_SVER OSI_BIT(1)
#define EQOS_MAC_FPE_CTS_SRSP OSI_BIT(2)
/* MTL_FPE_CTRL_STS */
#define EQOS_MTL_FPE_CTS_PEC (OSI_BIT(8) | OSI_BIT(9) | \
OSI_BIT(10) | OSI_BIT(11) | \
OSI_BIT(12) | OSI_BIT(13) | \
OSI_BIT(14) | OSI_BIT(15))
#define EQOS_MTL_FPE_CTS_PEC_SHIFT 8U
#define EQOS_MTL_FPE_CTS_PEC_MAX_SHIFT 16U
/* MTL FPE adv registers */
#define EQOS_MTL_FPE_ADV_HADV_MASK (0xFFFFU)
#define EQOS_MTL_FPE_ADV_HADV_VAL 100U
/* MTL_EST_CONTROL */
#define EQOS_MTL_EST_CONTROL_PTOV (OSI_BIT(24) | OSI_BIT(25) | \
OSI_BIT(26) | OSI_BIT(27) | \
OSI_BIT(28) | OSI_BIT(29) | \
OSI_BIT(30) | OSI_BIT(31))
#define EQOS_MTL_EST_CONTROL_PTOV_SHIFT 24U
#define EQOS_MTL_EST_CONTROL_CTOV (OSI_BIT(12) | OSI_BIT(13) | \
OSI_BIT(14) | OSI_BIT(15) | \
OSI_BIT(16) | OSI_BIT(17) | \
OSI_BIT(18) | OSI_BIT(19) | \
OSI_BIT(20) | OSI_BIT(21) | \
OSI_BIT(22) | OSI_BIT(23))
#define EQOS_MTL_EST_CONTROL_CTOV_SHIFT 12U
#define EQOS_MTL_EST_CONTROL_TILS (OSI_BIT(8) | OSI_BIT(9) | \
OSI_BIT(10))
#define EQOS_MTL_EST_CONTROL_LCSE (OSI_BIT(6) | OSI_BIT(5))
#define EQOS_MTL_EST_CONTROL_LCSE_SHIFT 5U
#define EQOS_MTL_EST_CONTROL_LCSE_VAL 0U
#define EQOS_MTL_EST_CONTROL_DFBS OSI_BIT(5)
#define EQOS_MTL_EST_CONTROL_DDBF OSI_BIT(4)
#define EQOS_MTL_EST_CONTROL_SSWL OSI_BIT(1)
#define EQOS_MTL_EST_CONTROL_EEST OSI_BIT(0)
/* EST controlOSI_BITmap */
#define EQOS_MTL_EST_EEST OSI_BIT(0)
#define EQOS_MTL_EST_SSWL OSI_BIT(1)
/* EST GCL controlOSI_BITmap */
#define EQOS_MTL_EST_ADDR_SHIFT 8U
#define EQOS_MTL_EST_ADDR_MASK (OSI_BIT(8) | OSI_BIT(9) | \
OSI_BIT(10) | OSI_BIT(11) | \
OSI_BIT(12) | OSI_BIT(13) | \
OSI_BIT(14) | OSI_BIT(15) | \
OSI_BIT(16) | OSI_BIT(17) | \
OSI_BIT(18) | OSI_BIT(19))
#define EQOS_MTL_EST_GCRR OSI_BIT(2)
#define EQOS_MTL_EST_SRWO OSI_BIT(0)
#define EQOS_MTL_EST_ERR0 OSI_BIT(20)
/* EST GCRA addresses */
#define EQOS_MTL_EST_BTR_LOW ((unsigned int)0x0 << \
EQOS_MTL_EST_ADDR_SHIFT)
#define EQOS_MTL_EST_BTR_HIGH ((unsigned int)0x1 << \
EQOS_MTL_EST_ADDR_SHIFT)
#define EQOS_MTL_EST_CTR_LOW ((unsigned int)0x2 << \
EQOS_MTL_EST_ADDR_SHIFT)
#define EQOS_MTL_EST_CTR_HIGH ((unsigned int)0x3 << \
EQOS_MTL_EST_ADDR_SHIFT)
#define EQOS_MTL_EST_CTR_HIGH_MAX 0xFFU
#define EQOS_MTL_EST_TER ((unsigned int)0x4 << \
EQOS_MTL_EST_ADDR_SHIFT)
#define EQOS_MTL_EST_LLR ((unsigned int)0x5 << \
EQOS_MTL_EST_ADDR_SHIFT)
/*EST MTL interrupt STATUS and ERR*/
#define EQOS_MTL_IS_ESTIS OSI_BIT(18)
/* MTL_EST_STATUS*/
#define EQOS_MTL_EST_STATUS_CGCE OSI_BIT(4)
#define EQOS_MTL_EST_STATUS_HLBS OSI_BIT(3)
#define EQOS_MTL_EST_STATUS_HLBF OSI_BIT(2)
#define EQOS_MTL_EST_STATUS_BTRE OSI_BIT(1)
#define EQOS_MTL_EST_STATUS_SWLC OSI_BIT(0)
#define EQOS_MTL_EST_ITRE_CGCE OSI_BIT(4)
#define EQOS_MTL_EST_ITRE_IEHS OSI_BIT(3)
#define EQOS_MTL_EST_ITRE_IEHF OSI_BIT(2)
#define EQOS_MTL_EST_ITRE_IEBE OSI_BIT(1)
#define EQOS_MTL_EST_ITRE_IECC OSI_BIT(0)
/** @} */ /** @} */
void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value);
@@ -425,7 +531,7 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value);
#define EQOS_MAC_RQC0R_MASK 0xFFU #define EQOS_MAC_RQC0R_MASK 0xFFU
#define EQOS_MAC_RQC1R_MASK 0xF77077U #define EQOS_MAC_RQC1R_MASK 0xF77077U
#define EQOS_MAC_RQC2R_MASK 0xFFFFFFFFU #define EQOS_MAC_RQC2R_MASK 0xFFFFFFFFU
#define EQOS_MAC_IMR_MASK 0x47039U #define EQOS_MAC_IMR_MASK 0x67039U
#define EQOS_MAC_MA0HR_MASK 0xFFFFFU #define EQOS_MAC_MA0HR_MASK 0xFFFFFU
#define EQOS_MAC_MA0LR_MASK 0xFFFFFFFFU #define EQOS_MAC_MA0LR_MASK 0xFFFFFFFFU
#define EQOS_MAC_TCR_MASK 0x1107FF03U #define EQOS_MAC_TCR_MASK 0x1107FF03U
@@ -433,7 +539,6 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value);
#define EQOS_MAC_TAR_MASK 0xFFFFFFFFU #define EQOS_MAC_TAR_MASK 0xFFFFFFFFU
#define EQOS_RXQ_DMA_MAP0_MASK 0x13131313U #define EQOS_RXQ_DMA_MAP0_MASK 0x13131313U
#define EQOS_RXQ_EN_MASK (OSI_BIT(0) | OSI_BIT(1)) #define EQOS_RXQ_EN_MASK (OSI_BIT(0) | OSI_BIT(1))
#define EQOS_MTL_TXQ_OP_MODE_MASK 0xFF007EU #define EQOS_MTL_TXQ_OP_MODE_MASK 0xFF007EU
#define EQOS_MTL_TXQ_QW_MASK 0x1FFFFFU #define EQOS_MTL_TXQ_QW_MASK 0x1FFFFFU
#define EQOS_MTL_RXQ_OP_MODE_MASK 0xFFFFFFBU #define EQOS_MTL_RXQ_OP_MODE_MASK 0xFFFFFFBU

View File

@@ -381,4 +381,22 @@ void eqos_read_mmc(struct osi_core_priv_data *const osi_core)
mmc->mmc_rx_icmp_err_octets = mmc->mmc_rx_icmp_err_octets =
update_mmc_val(osi_core, mmc->mmc_rx_icmp_err_octets, update_mmc_val(osi_core, mmc->mmc_rx_icmp_err_octets,
MMC_RXICMP_ERR_OCTETS); MMC_RXICMP_ERR_OCTETS);
mmc->mmc_tx_fpe_frag_cnt =
update_mmc_val(osi_core, mmc->mmc_tx_fpe_frag_cnt,
MMC_TX_FPE_FRAG_COUNTER);
mmc->mmc_tx_fpe_hold_req_cnt =
update_mmc_val(osi_core, mmc->mmc_tx_fpe_hold_req_cnt,
MMC_TX_HOLD_REQ_COUNTER);
mmc->mmc_rx_packet_reass_err_cnt =
update_mmc_val(osi_core, mmc->mmc_rx_packet_reass_err_cnt,
MMC_RX_PKT_ASSEMBLY_ERR_CNTR);
mmc->mmc_rx_packet_smd_err_cnt =
update_mmc_val(osi_core, mmc->mmc_rx_packet_smd_err_cnt,
MMC_RX_PKT_SMD_ERR_CNTR);
mmc->mmc_rx_packet_asm_ok_cnt =
update_mmc_val(osi_core, mmc->mmc_rx_packet_asm_ok_cnt,
MMC_RX_PKT_ASSEMBLY_OK_CNTR);
mmc->mmc_rx_fpe_fragment_cnt =
update_mmc_val(osi_core, mmc->mmc_rx_fpe_fragment_cnt,
MMC_RX_FPE_FRAG_CNTR);
} }

View File

@@ -112,7 +112,13 @@
#define MMC_RXTCP_GD_OCTETS 0x00878 #define MMC_RXTCP_GD_OCTETS 0x00878
#define MMC_RXTCP_ERR_OCTETS 0x0087c #define MMC_RXTCP_ERR_OCTETS 0x0087c
#define MMC_RXICMP_GD_OCTETS 0x00880 #define MMC_RXICMP_GD_OCTETS 0x00880
#define MMC_RXICMP_ERR_OCTETS 0x00884U #define MMC_RXICMP_ERR_OCTETS 0x00884
#define MMC_TX_FPE_FRAG_COUNTER 0x008A8
#define MMC_TX_HOLD_REQ_COUNTER 0x008AC
#define MMC_RX_PKT_ASSEMBLY_ERR_CNTR 0x008C8
#define MMC_RX_PKT_SMD_ERR_CNTR 0x008CC
#define MMC_RX_PKT_ASSEMBLY_OK_CNTR 0x008D0
#define MMC_RX_FPE_FRAG_CNTR 0x008D4
/** @} */ /** @} */
void eqos_read_mmc(struct osi_core_priv_data *const osi_core); void eqos_read_mmc(struct osi_core_priv_data *const osi_core);

View File

@@ -1005,6 +1005,30 @@ int osi_config_rss(struct osi_core_priv_data *const osi_core)
return ops_p->config_rss(osi_core); return ops_p->config_rss(osi_core);
} }
int osi_hw_config_est(struct osi_core_priv_data *osi_core,
struct osi_est_config *est)
{
if (validate_args(osi_core) < 0) {
return -1;
}
if (est == OSI_NULL) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
"EST data is NULL", 0ULL);
return -1;
}
if ((osi_core->flow_ctrl & OSI_FLOW_CTRL_TX) ==
OSI_FLOW_CTRL_TX) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
"TX Flow control enabled, please disable it",
0ULL);
return -1;
}
return ops_p->hw_config_est(osi_core, est);
}
nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core,
const nveu32_t lb_mode) const nveu32_t lb_mode)
{ {
@@ -1022,6 +1046,22 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core,
/* Configure MAC loopback */ /* Configure MAC loopback */
return ops_p->config_mac_loopback(osi_core, lb_mode); return ops_p->config_mac_loopback(osi_core, lb_mode);
} }
int osi_hw_config_fpe(struct osi_core_priv_data *osi_core,
struct osi_fpe_config *fpe)
{
if (validate_args(osi_core) < 0) {
return -1;
}
if (fpe == OSI_NULL) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
"FPE data is NULL", 0ULL);
return -1;
}
return ops_p->hw_config_fpe(osi_core, fpe);
}
#endif /* !OSI_STRIPPED_LIB */ #endif /* !OSI_STRIPPED_LIB */
nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core,