From a0c20c02f6dc60a94b1b1d15a77bc6f719916b0e Mon Sep 17 00:00:00 2001 From: Bhadram Varka Date: Mon, 20 Sep 2021 17:30:34 +0530 Subject: [PATCH] osi: mgbe: add handling of tx errors handle Tx buffer underflow handle Tx jabber timeout handle Tx IP header error handle Tx Payload checksum error Bug 200565898 Change-Id: I2de4cd11580251f0387039c1f8f3c39792c1ab65 Signed-off-by: narayanr Signed-off-by: Bhadram Varka Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2596092 Tested-by: mobile promotions Reviewed-by: Rakesh Goyal Reviewed-by: Krishna Thota Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 16 +++++++++ osi/core/mgbe_core.c | 82 +++++++++++++++++++++++++++++++++++++++----- osi/core/mgbe_core.h | 9 +++++ 3 files changed, 99 insertions(+), 8 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 4bfd577..2c8ea5b 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1139,6 +1139,20 @@ struct core_padctrl { unsigned int pad_calibration_enable; }; +/** + * @brief OSI CORE packet error stats + */ +struct osi_core_pkt_err_stats { + /** IP Header Error */ + nveu64_t mgbe_ip_header_err; + /** Jabber time out Error */ + nveu64_t mgbe_jabber_timeout_err; + /** Payload Checksum Error */ + nveu64_t mgbe_payload_cs_err; + /** Under Flow Error */ + nveu64_t mgbe_tx_underflow_err; +}; + /** * @brief The OSI Core (MAC & MTL) private data structure. */ @@ -1260,6 +1274,8 @@ struct osi_core_priv_data { struct core_padctrl padctrl; /** MGBE MAC instance ID's */ nveu32_t instance_id; + /** Packet error stats */ + struct osi_core_pkt_err_stats pkt_err_stats; }; /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 359475a..698db59 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2226,6 +2226,7 @@ static void update_rfa_rfd(unsigned int rx_fifo, unsigned int *value) * 4) Configure Tx and Rx MTL Queue sizes * 5) Configure TxQ weight * 6) Enable Rx Queues + * 7) Enable TX Underflow Interrupt for MTL Q * * @param[in] qinx: Queue number that need to be configured. * @param[in] osi_core: OSI core private data. @@ -2314,6 +2315,13 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, (MGBE_MAC_RXQC0_RXQEN_SHIFT(qinx))); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_RQC0R); + + /* Enable TX Underflow Interrupt for MTL Q */ + value = osi_readl((unsigned char *)osi_core->base + + MGBE_MTL_QINT_ENABLE(qinx)); + value |= MGBE_MTL_QINT_TXUIE; + osi_writel(value, (unsigned char *)osi_core->base + + MGBE_MTL_QINT_ENABLE(qinx)); return 0; } @@ -2602,8 +2610,9 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* Read MAC IMR Register */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_IER); /* RGSMIIIM - RGMII/SMII interrupt and TSIE Enable */ + /* TXESIE - Transmit Error Status Interrupt Enable */ /* TODO: LPI need to be enabled during EEE implementation */ - value |= (MGBE_IMR_RGSMIIIE | MGBE_IMR_TSIE); + value |= (MGBE_IMR_RGSMIIIE | MGBE_IMR_TSIE | MGBE_IMR_TXESIE); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); /* Enable common interrupt at wrapper level */ @@ -3248,6 +3257,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, struct core_local *l_core = (struct core_local *)osi_core; nveu32_t mac_isr = 0; nveu32_t mac_ier = 0; + nveu32_t tx_errors = 0; mac_isr = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MAC_ISR); @@ -3263,6 +3273,35 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, mgbe_handle_mac_fpe_intrs(osi_core); mac_isr &= ~MGBE_MAC_IMR_FPEIS; } + /* Check for any MAC Transmit Error Status Interrupt */ + if ((mac_isr & MGBE_IMR_TXESIE) == MGBE_IMR_TXESIE) { + /* Check for the type of Tx error by reading MAC_Rx_Tx_Status + * register + */ + tx_errors = osi_readl((unsigned char *)osi_core->base + + MGBE_MAC_RX_TX_STS); + if ((tx_errors & MGBE_MAC_TX_TJT) == MGBE_MAC_TX_TJT) { + /* increment Tx Jabber timeout stats */ + osi_core->pkt_err_stats.mgbe_jabber_timeout_err = + osi_update_stats_counter( + osi_core->pkt_err_stats.mgbe_jabber_timeout_err, + 1UL); + } + if ((tx_errors & MGBE_MAC_TX_IHE) == MGBE_MAC_TX_IHE) { + /* IP Header Error */ + osi_core->pkt_err_stats.mgbe_ip_header_err = + osi_update_stats_counter( + osi_core->pkt_err_stats.mgbe_ip_header_err, + 1UL); + } + if ((tx_errors & MGBE_MAC_TX_PCE) == MGBE_MAC_TX_PCE) { + /* Payload Checksum error */ + osi_core->pkt_err_stats.mgbe_payload_cs_err = + osi_update_stats_counter( + osi_core->pkt_err_stats.mgbe_payload_cs_err, + 1UL); + } + } osi_writela(osi_core, mac_isr, (unsigned char *)osi_core->base + MGBE_MAC_ISR); @@ -3610,7 +3649,8 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * * @note MAC should be init and started. see osi_start_mac() */ -static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) +static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, + unsigned int mtl_isr) { unsigned int val = 0U; unsigned int sch_err = 0U; @@ -3619,6 +3659,32 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) unsigned int i = 0; unsigned long stat_val = 0U; unsigned int value = 0U; + unsigned int qstatus = 0U; + unsigned int qinx = 0U; + + /* Check for all MTL queues */ + for (i = 0; i < osi_core->num_mtl_queues; i++) { + qinx = osi_core->mtl_queues[i]; + if (mtl_isr & OSI_BIT(qinx)) { + /* check if Q has underflow error */ + qstatus = osi_readl((unsigned char *)osi_core->base + + MGBE_MTL_QINT_STATUS(qinx)); + /* Transmit Queue Underflow Interrupt Status */ + if (qstatus & MGBE_MTL_QINT_TXUNIFS) { + osi_core->pkt_err_stats.mgbe_tx_underflow_err = + osi_update_stats_counter( + osi_core->pkt_err_stats.mgbe_tx_underflow_err, + 1UL); + } + /* Clear interrupt status by writing back with 1 */ + osi_writel(1U, (unsigned char *)osi_core->base + + MGBE_MTL_QINT_STATUS(qinx)); + } + } + + if ((mtl_isr & MGBE_MTL_IS_ESTIS) != MGBE_MTL_IS_ESTIS) { + return; + } val = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); @@ -3725,6 +3791,10 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) /* clear EST status register as interrupt is handled */ osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); + + mtl_isr &= ~MGBE_MTL_IS_ESTIS; + osi_writela(osi_core, mtl_isr, (unsigned char *)osi_core->base + + MGBE_MTL_INTR_STATUS); } /** @@ -3908,12 +3978,8 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, (unsigned char *)base + MGBE_MTL_INTR_STATUS); - if (((mtl_isr & MGBE_MTL_IS_ESTIS) == MGBE_MTL_IS_ESTIS) && - ((dma_isr & MGBE_DMA_ISR_MTLIS) == MGBE_DMA_ISR_MTLIS)) { - mgbe_handle_mtl_intrs(osi_core); - mtl_isr &= ~MGBE_MTL_IS_ESTIS; - osi_writela(osi_core, mtl_isr, (unsigned char *)base + - MGBE_MTL_INTR_STATUS); + if ((dma_isr & MGBE_DMA_ISR_MTLIS) == MGBE_DMA_ISR_MTLIS) { + mgbe_handle_mtl_intrs(osi_core, mtl_isr); } /* Clear common interrupt status in wrapper register */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d99a63c..d6da589 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -74,6 +74,7 @@ #define MGBE_MAC_RQC2R 0x00A8 #define MGBE_MAC_ISR 0x00B0 #define MGBE_MAC_IER 0x00B4 +#define MGBE_MAC_RX_TX_STS 0x00B8 #define MGBE_MAC_PMTCSR 0x00C0 #define MGBE_MAC_LPI_CSR 0x00D0 #define MGBE_MAC_LPI_TIMER_CTRL 0x00D4 @@ -293,6 +294,8 @@ #define MGBE_MTL_TCQ_ETS_LCR(x) ((0x0080U * (x)) + 0x1124U) #define MGBE_MTL_CHX_RX_OP_MODE(x) ((0x0080U * (x)) + 0x1140U) #define MGBE_MTL_RXQ_FLOW_CTRL(x) ((0x0080U * (x)) + 0x1150U) +#define MGBE_MTL_QINT_ENABLE(x) ((0x0080U * (x)) + 0x1170U) +#define MGBE_MTL_QINT_STATUS(x) ((0x0080U * (x)) + 0x1174U) #define MGBE_MTL_TC_PRTY_MAP0 0x1040 #define MGBE_MTL_TC_PRTY_MAP1 0x1044 #define MGBE_MTL_RXP_CS 0x10A0 @@ -409,6 +412,8 @@ #define MGBE_MTL_TXQEN OSI_BIT(3) #define MGBE_MTL_RSF OSI_BIT(5) #define MGBE_MTL_TCQ_QW_ISCQW OSI_BIT(4) +#define MGBE_MTL_QINT_TXUNIFS OSI_BIT(0) +#define MGBE_MTL_QINT_TXUIE OSI_BIT(0) #define MGBE_MAC_RMCR_ACS OSI_BIT(1) #define MGBE_MAC_RMCR_CST OSI_BIT(2) #define MGBE_MAC_RMCR_IPC OSI_BIT(9) @@ -458,6 +463,7 @@ #define MGBE_MAC_RQC4R_PMCBCQ_SHIFT 24U #define MGBE_IMR_RGSMIIIE OSI_BIT(0) #define MGBE_IMR_TSIE OSI_BIT(12) +#define MGBE_IMR_TXESIE OSI_BIT(13) #define MGBE_IMR_FPEIE OSI_BIT(15) #define MGBE_MAC_IMR_FPEIS OSI_BIT(16) #define MGBE_ISR_TSIS OSI_BIT(12) @@ -530,6 +536,9 @@ #define MGBE_MAC_RSS_ADDR_RSSIA_SHIFT 8U #define MGBE_MAC_RSS_ADDR_OB OSI_BIT(0) #define MGBE_MAC_RSS_ADDR_CT OSI_BIT(1) +#define MGBE_MAC_TX_TJT OSI_BIT(0) +#define MGBE_MAC_TX_IHE OSI_BIT(12) +#define MGBE_MAC_TX_PCE OSI_BIT(13) /* DMA SBUS */ #define MGBE_DMA_SBUS_UNDEF OSI_BIT(0) #define MGBE_DMA_SBUS_BLEN256 OSI_BIT(7)