From acbb40e98fe1083dc4f1ce6416cb9b68b8593b3a Mon Sep 17 00:00:00 2001 From: narayanr Date: Fri, 6 Mar 2020 10:33:59 +0530 Subject: [PATCH] nvethernetrm: drop rx packets longer than current MTU Issue: When JE is set, HW will accept any valid packet on Rx upto 9K or 16K (depending on GPSCLE bit), irrespective of whether MTU set is lower than these specific values. When Rx buf len is allocated to be exactly same as MTU, HW will consume more than 1 Rx desc to place the larger packet. Fix: Drop Rx packets which are longer than currently set MTU since HW cannot drop them. Bug 2870545 Signed-off-by: narayanr Change-Id: I869f4858f8d2b502a3965dc2ca40cda8805f9886 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2308379 Tested-by: mobile promotions Reviewed-by: mobile promotions --- include/osi_common.h | 1 + include/osi_dma.h | 2 +- include/osi_dma_txrx.h | 3 ++- osi/dma/osi_dma_txrx.c | 20 +++++++++++++++++++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 8a105ea..76eacfb 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -227,6 +227,7 @@ #define OSI_MAC_HW_EQOS 0U #define OSI_ETH_ALEN 6U +#define BOOLEAN_FALSE (0U != 0U) #define OSI_NULL ((void *)0) #define OSI_ENABLE 1U #define OSI_NONE 0U diff --git a/include/osi_dma.h b/include/osi_dma.h index 9f4af2c..efc9726 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -104,7 +104,7 @@ * @{ */ /* Rx swcx flags */ -#define OSI_RX_SWCX_PTP OSI_BIT(0) +#define OSI_RX_SWCX_REUSE OSI_BIT(0) #define OSI_RX_SWCX_BUF_VALID OSI_BIT(1) /** @} */ diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 97c0c5c..4eabb09 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -65,6 +65,7 @@ #define RDES3_IOC OSI_BIT(30) #define RDES3_B1V OSI_BIT(24) #define RDES3_LD OSI_BIT(28) +#define RDES3_FD OSI_BIT(29) #define RDES3_ERR_CRC OSI_BIT(24) #define RDES3_ERR_GP OSI_BIT(23) #define RDES3_ERR_WD OSI_BIT(22) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 9c6210f..bd09416 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -226,6 +226,24 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); + /* WHen JE is set, HW will accept any valid packet on Rx upto + * 9K or 16K (depending on GPSCLE bit), irrespective of whether + * MTU set is lower than these specific values. When Rx buf len + * is allocated to be exactly same as MTU, HW will consume more + * than 1 Rx desc. to place the larger packet and will set the + * LD bit in RDES3 accordingly. + * Restrict such Rx packets (which are longer than currently + * set MTU on DUT), and drop them in driver since HW cannot + * drop them. Also make use of swcx flags so that OSD can skip + * DMA buffer allocation and DMA mapping for those descriptors. + * If data is spread across multiple descriptors, drop packet + */ + if ((((rx_desc->rdes3 & RDES3_FD) == RDES3_FD) && + (rx_desc->rdes3 & RDES3_LD) == RDES3_LD) == BOOLEAN_FALSE) { + rx_swcx->flags |= OSI_RX_SWCX_REUSE; + continue; + } + /* get the length of the packet */ rx_pkt_cx->pkt_len = rx_desc->rdes3 & RDES3_PKT_LEN; @@ -257,7 +275,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * software context addresses directly since * those are valid. */ - ptp_rx_swcx->flags |= OSI_RX_SWCX_PTP; + ptp_rx_swcx->flags |= OSI_RX_SWCX_REUSE; /* Context descriptor was consumed. Its skb * and DMA mapping will be recycled */