Skip to content

Commit

Permalink
ftgmac100: Cleanup rx checksum handling
Browse files Browse the repository at this point in the history
Read the descriptor field only once and check for IP header
checksum errors as well

Change-Id: I93c0b30101b5394672e06746d91eb43d150c1842
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Wei-Chung Wen <wei-chung.wen@foxconn.com>
  • Loading branch information
Wei-Chung Wen authored and JasonLuo701 committed Aug 11, 2017
1 parent 0e05e4a commit 6052b9a
Showing 1 changed file with 25 additions and 38 deletions.
63 changes: 25 additions & 38 deletions drivers/net/ethernet/faraday/ftgmac100.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,31 +322,11 @@ static dma_addr_t ftgmac100_rxdes_get_dma_addr(struct ftgmac100_rxdes *rxdes)
return le32_to_cpu(rxdes->rxdes3);
}

static bool ftgmac100_rxdes_is_tcp(struct ftgmac100_rxdes *rxdes)
static inline bool ftgmac100_rxdes_csum_err(struct ftgmac100_rxdes *rxdes)
{
return (rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_PROT_MASK)) ==
cpu_to_le32(FTGMAC100_RXDES1_PROT_TCPIP);
}

static bool ftgmac100_rxdes_is_udp(struct ftgmac100_rxdes *rxdes)
{
return (rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_PROT_MASK)) ==
cpu_to_le32(FTGMAC100_RXDES1_PROT_UDPIP);
}

static bool ftgmac100_rxdes_tcpcs_err(struct ftgmac100_rxdes *rxdes)
{
return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_TCP_CHKSUM_ERR);
}

static bool ftgmac100_rxdes_udpcs_err(struct ftgmac100_rxdes *rxdes)
{
return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_UDP_CHKSUM_ERR);
}

static bool ftgmac100_rxdes_ipcs_err(struct ftgmac100_rxdes *rxdes)
{
return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_IP_CHKSUM_ERR);
return !!(rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_TCP_CHKSUM_ERR |
FTGMAC100_RXDES1_UDP_CHKSUM_ERR |
FTGMAC100_RXDES1_IP_CHKSUM_ERR));
}

static inline struct page **ftgmac100_rxdes_page_slot(struct ftgmac100 *priv,
Expand Down Expand Up @@ -426,11 +406,6 @@ static bool ftgmac100_rx_packet_error(struct ftgmac100 *priv,

netdev->stats.rx_crc_errors++;
error = true;
} else if (unlikely(ftgmac100_rxdes_ipcs_err(rxdes))) {
if (net_ratelimit())
netdev_info(netdev, "rx IP checksum err\n");

error = true;
}

if (unlikely(ftgmac100_rxdes_frame_too_long(rxdes))) {
Expand Down Expand Up @@ -506,14 +481,23 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
if (unlikely(ftgmac100_rxdes_multicast(rxdes)))
netdev->stats.multicast++;

/*
* It seems that HW does checksum incorrectly with fragmented packets,
* so we are conservative here - if HW checksum error, let software do
* the checksum again.
/* If the HW found checksum errors, bounce it to software.
*
* If we didn't, we need to see if the packet was recognized
* by HW as one of the supported checksummed protocols before
* we accept the HW test results.
*/
if ((ftgmac100_rxdes_is_tcp(rxdes) && !ftgmac100_rxdes_tcpcs_err(rxdes)) ||
(ftgmac100_rxdes_is_udp(rxdes) && !ftgmac100_rxdes_udpcs_err(rxdes)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
if (netdev->features & NETIF_F_RXCSUM) {
__le32 csum_vlan = rxdes->rxdes1;
__le32 err_bits = cpu_to_le32(FTGMAC100_RXDES1_TCP_CHKSUM_ERR |
FTGMAC100_RXDES1_UDP_CHKSUM_ERR |
FTGMAC100_RXDES1_IP_CHKSUM_ERR);
if ((csum_vlan & err_bits) ||
!(csum_vlan & cpu_to_le32(FTGMAC100_RXDES1_PROT_MASK)))
skb->ip_summed = CHECKSUM_NONE;
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
}

do {
dma_addr_t map = ftgmac100_rxdes_get_dma_addr(rxdes);
Expand Down Expand Up @@ -552,7 +536,10 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
netdev->stats.rx_bytes += skb->len;

/* push packet to protocol stack */
napi_gro_receive(&priv->napi, skb);
if (skb->ip_summed == CHECKSUM_NONE)
netif_receive_skb(skb);
else
napi_gro_receive(&priv->napi, skb);

(*processed)++;
return true;
Expand Down Expand Up @@ -1423,7 +1410,7 @@ static int ftgmac100_probe(struct platform_device *pdev)
* when NCSI is enabled on the interface. It doesn't work
* in that case.
*/
netdev->features = NETIF_F_IP_CSUM | NETIF_F_GRO;
netdev->features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_GRO;
if (priv->use_ncsi ||
of_get_property(pdev->dev.of_node, "no-hw-checksum", NULL))
netdev->features &= ~NETIF_F_IP_CSUM;
Expand Down

0 comments on commit 6052b9a

Please sign in to comment.