diff --git a/include/mmc.h b/include/mmc.h index 2f5e282..b9a88eb 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -527,6 +527,27 @@ struct osi_mmc_counters { * segment that had checksum errors. This counter does not count * IP header bytes */ 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; }; /** diff --git a/include/osi_common.h b/include/osi_common.h index 42934b1..24747d1 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -129,6 +129,14 @@ #define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PTP_REQ_CLK_FREQ 250000000U #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 @@ -272,10 +280,6 @@ * @brief osi_update_stats_counter - update value by increment passed * as parameter * - * @note - * Algorithm: - * - Check for boundary and return sum - * * @param[in] last_value: last value of stat counter * @param[in] incr: increment value * diff --git a/include/osi_core.h b/include/osi_core.h index 7439f1e..11ce4a1 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -178,7 +178,7 @@ typedef my_lint_64 nvel64_t; #define OSI_VLAN_ACTION_DEL 0x0U #define OSI_RXQ_ROUTE_PTP 0U #define OSI_DELAY_1000US 1000U - +#define OSI_DELAY_1US 1U /** * @addtogroup RSS related information * @@ -619,6 +619,62 @@ struct osi_core_avb_algorithm { }; #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 */ @@ -627,29 +683,29 @@ struct osi_ptp_config { * * Enable Timestamp, Fine Timestamp, 1 nanosecond accuracy * are enabled by default. - * + * * Need to set below bit fields accordingly as per the requirements. - * + * * Enable Timestamp for All Packets OSI_BIT(8) - * + * * Enable PTP Packet Processing for Version 2 Format OSI_BIT(10) - * + * * Enable Processing of PTP over Ethernet Packets OSI_BIT(11) - * + * * Enable Processing of PTP Packets Sent over IPv6-UDP OSI_BIT(12) - * + * * Enable Processing of PTP Packets Sent over IPv4-UDP OSI_BIT(13) - * + * * Enable Timestamp Snapshot for Event Messages OSI_BIT(14) - * + * * Enable Snapshot for Messages Relevant to Master OSI_BIT(15) - * + * * Select PTP packets for Taking Snapshots OSI_BIT(16) - * + * * Select PTP packets for Taking Snapshots OSI_BIT(17) - * + * * Select PTP packets for Taking Snapshots (OSI_BIT(16) + OSI_BIT(17)) - * + * * AV 802.1AS Mode Enable OSI_BIT(28) * * if ptp_filter is set to Zero then Time stamping is disabled */ @@ -737,6 +793,10 @@ struct osi_core_priv_data { nveu32_t rxq_ctrl[OSI_MGBE_MAX_NUM_CHANS]; /** Rx MTl Queue mapping based on User Priority field */ 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 */ nveu32_t mac; /** MAC version */ @@ -786,6 +846,16 @@ struct osi_core_priv_data { unsigned short vlan_filter_cnt; /** RSS core structure */ 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. */ 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 */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index d763adb..6d4d019 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -204,6 +204,12 @@ struct core_ops { struct osi_hw_features *hw_feat); /** Called to configure RSS for MAC */ 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); }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 26174e4..e1972dd 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -21,6 +21,7 @@ */ #include "../osi/common/common.h" +#include #include #include "eqos_core.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); } +/** + * @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 * @@ -1509,12 +1639,69 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, /* configure EQOS DMA */ 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 */ osi_core->l3l4_filter_bitmask = OSI_NONE; 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 * @@ -1554,8 +1741,10 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, mac_imr = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); mac_isr = (mac_isr & mac_imr); + /* 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; } @@ -1595,6 +1784,12 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, } else { /* 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. * @@ -1677,6 +1977,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t i = 0; nveu32_t dma_sr = 0; nveu32_t dma_ier = 0; + unsigned int mtl_isr = 0; dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR); 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); + /* 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); } +/** + * @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 * @@ -4515,4 +5154,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->set_mdc_clk_rate = eqos_set_mdc_clk_rate; ops->config_mac_loopback = eqos_config_mac_loopback; #endif /* !OSI_STRIPPED_LIB */ + ops->hw_config_est = eqos_hw_config_est; + ops->hw_config_fpe = eqos_hw_config_fpe; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 9937c75..4d48e2b 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -100,6 +100,8 @@ #define EQOS_MAC_MDIO_ADDRESS 0x0200 #define EQOS_MAC_MDIO_DATA 0x0204 #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_ADDRH(x) ((0x0008U * (x)) + 0x0300U) #define EQOS_MAC_MA0LR 0x0304 @@ -134,7 +136,18 @@ * @{ */ #define EQOS_MTL_OP_MODE 0x0C00 +#define EQOS_MTL_INTR_STATUS 0x0C20 #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_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) #define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) @@ -194,6 +207,11 @@ #define EQOS_MCR_CST OSI_BIT(21) #define EQOS_MCR_GPSLCE OSI_BIT(23) #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_LNKMOD OSI_BIT(16) #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_MAC_RQC1R_MCBCQ1 OSI_BIT(16) #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_DMA_ISR_MTLIS OSI_BIT(16) #define EQOS_DMA_ISR_MACIS OSI_BIT(17) #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_DMA_SBUS_RD_OSR_LMT 0x001F0000U #define EQOS_DMA_SBUS_WR_OSR_LMT 0x1F000000U @@ -408,6 +431,89 @@ (TEGRA_SID_EQOS_CH5) |\ (TEGRA_SID_EQOS)) #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); @@ -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_RQC1R_MASK 0xF77077U #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_MA0LR_MASK 0xFFFFFFFFU #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_RXQ_DMA_MAP0_MASK 0x13131313U #define EQOS_RXQ_EN_MASK (OSI_BIT(0) | OSI_BIT(1)) - #define EQOS_MTL_TXQ_OP_MODE_MASK 0xFF007EU #define EQOS_MTL_TXQ_QW_MASK 0x1FFFFFU #define EQOS_MTL_RXQ_OP_MODE_MASK 0xFFFFFFBU diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index a9cb69d..6b16d64 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -381,4 +381,22 @@ void eqos_read_mmc(struct osi_core_priv_data *const osi_core) mmc->mmc_rx_icmp_err_octets = update_mmc_val(osi_core, mmc->mmc_rx_icmp_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); } diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h index a76630d..8021e0b 100644 --- a/osi/core/eqos_mmc.h +++ b/osi/core/eqos_mmc.h @@ -112,7 +112,13 @@ #define MMC_RXTCP_GD_OCTETS 0x00878 #define MMC_RXTCP_ERR_OCTETS 0x0087c #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); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 3804649..c3d90b4 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -1005,6 +1005,30 @@ int osi_config_rss(struct osi_core_priv_data *const 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, 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 */ 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 */ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core,