diff options
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 54 |
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 */ |
