summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index fc585c562eba..f68ae9926689 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5176,6 +5176,23 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
stmmac_enable_dma_reception(priv, priv->ioaddr, queue);
}
+/**
+ * stmmac_fcs_trimming - FCS field length
+ * @priv: driver private structure
+ * @status: frame Rx-status
+ * Description :
+ * Retrieve FCS length required to be trimmed of the Rx frame.
+ */
+static unsigned int stmmac_fcs_trimming(struct stmmac_priv *priv, int status)
+{
+ bool rxfcs = priv->dev->features & NETIF_F_RXFCS;
+
+ if (rxfcs)
+ return 0;
+
+ return ETH_FCS_LEN;
+}
+
static unsigned int stmmac_rx_buf1_len(struct stmmac_priv *priv,
struct dma_desc *p,
int status, unsigned int len)
@@ -5205,10 +5222,13 @@ static unsigned int stmmac_rx_buf1_len(struct stmmac_priv *priv,
return len ? plen : plen - stmmac_fs_offset();
}
- plen = stmmac_get_rx_frame_len(priv, p);
+ /* Last descriptor and not split header and secondary buffer used */
+ plen = stmmac_get_rx_frame_len(priv, p) - len;
+ if (plen > priv->dma_conf.dma_buf_sz)
+ return priv->dma_conf.dma_buf_sz;
- /* First descriptor and last descriptor and not split header */
- return min_t(unsigned int, priv->dma_conf.dma_buf_sz, plen);
+ /* Last descriptor and last buffer with FCS clipped of */
+ return plen - stmmac_fcs_trimming(priv, status);
}
static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
@@ -5239,10 +5259,13 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
return priv->dma_conf.dma_buf_sz;
- /* GMAC4 or last descriptor */
- plen = stmmac_get_rx_frame_len(priv, p);
+ /* GMAC4 or last descriptor and secondary buffer unused */
+ plen = stmmac_get_rx_frame_len(priv, p) - len;
+ if (!plen)
+ return 0;
- return plen - len;
+ /* Last descriptor and last buffer with FCS clipped of */
+ return plen - stmmac_fcs_trimming(priv, status);
}
static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
@@ -5689,12 +5712,6 @@ read_again:
buf1_len = stmmac_rx_buf1_len(priv, p, status, len);
len += buf1_len;
- /* ACS is disabled; strip manually. */
- if (likely(!(status & rx_not_ls))) {
- buf1_len -= ETH_FCS_LEN;
- len -= ETH_FCS_LEN;
- }
-
/* RX buffer is good and fit into a XSK pool buffer */
buf->xdp->data_end = buf->xdp->data + buf1_len;
xsk_buff_dma_sync_for_cpu(buf->xdp);
@@ -5861,17 +5878,6 @@ read_again:
buf2_len = stmmac_rx_buf2_len(priv, p, status, len);
len += buf2_len;
- /* ACS is disabled; strip manually. */
- if (likely(!(status & rx_not_ls))) {
- if (buf2_len) {
- buf2_len -= ETH_FCS_LEN;
- len -= ETH_FCS_LEN;
- } else if (buf1_len) {
- buf1_len -= ETH_FCS_LEN;
- len -= ETH_FCS_LEN;
- }
- }
-
if (!skb) {
unsigned int pre_len, sync_len;
@@ -8425,6 +8431,8 @@ static int __stmmac_dvr_probe(struct device *device,
dwmac_is_xmac(priv->plat->core_type))
ndev->hw_features |= NETIF_F_RXALL;
+ ndev->hw_features |= NETIF_F_RXFCS;
+
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
#ifdef STMMAC_VLAN_TAG_USED
/* Both mac100 and gmac support receive VLAN tag detection */