net: fec: align IP header in hardware
The FEC receive accelerator (RACC) supports shifting the data payload of received packets by 16-bits, which aligns the payload (IP header) on a 4-byte boundary, which is, if not required, at least strongly suggested by the Linux networking layer. Without this patch, a huge number of alignment faults will be taken by the IP stack, as seen in /proc/cpu/alignment: ~/$ cat /proc/cpu/alignment User: 0 System: 72645 (inet_gro_receive+0x104/0x27c) Skipped: 0 Half: 0 Word: 0 DWord: 0 Multi: 72645 User faults: 3 (fixup+warn) This patch was suggested by Andrew Lunn in this message to linux-netdev: http://marc.info/?l=linux-arm-kernel&m=147465452108384&w=2 and adapted from a patch by Russell King from 2014: http://git.arm.linux.org.uk/cgit/linux-arm.git/commit/?id=70d8a8a Signed-off-by: Eric Nelson <eric@nelint.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
97dc499c1a
commit
3ac72b7b63
@ -180,6 +180,7 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
|
|||||||
/* FEC receive acceleration */
|
/* FEC receive acceleration */
|
||||||
#define FEC_RACC_IPDIS (1 << 1)
|
#define FEC_RACC_IPDIS (1 << 1)
|
||||||
#define FEC_RACC_PRODIS (1 << 2)
|
#define FEC_RACC_PRODIS (1 << 2)
|
||||||
|
#define FEC_RACC_SHIFT16 BIT(7)
|
||||||
#define FEC_RACC_OPTIONS (FEC_RACC_IPDIS | FEC_RACC_PRODIS)
|
#define FEC_RACC_OPTIONS (FEC_RACC_IPDIS | FEC_RACC_PRODIS)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -945,9 +946,11 @@ fec_restart(struct net_device *ndev)
|
|||||||
|
|
||||||
#if !defined(CONFIG_M5272)
|
#if !defined(CONFIG_M5272)
|
||||||
if (fep->quirks & FEC_QUIRK_HAS_RACC) {
|
if (fep->quirks & FEC_QUIRK_HAS_RACC) {
|
||||||
/* set RX checksum */
|
|
||||||
val = readl(fep->hwp + FEC_RACC);
|
val = readl(fep->hwp + FEC_RACC);
|
||||||
|
/* align IP header */
|
||||||
|
val |= FEC_RACC_SHIFT16;
|
||||||
if (fep->csum_flags & FLAG_RX_CSUM_ENABLED)
|
if (fep->csum_flags & FLAG_RX_CSUM_ENABLED)
|
||||||
|
/* set RX checksum */
|
||||||
val |= FEC_RACC_OPTIONS;
|
val |= FEC_RACC_OPTIONS;
|
||||||
else
|
else
|
||||||
val &= ~FEC_RACC_OPTIONS;
|
val &= ~FEC_RACC_OPTIONS;
|
||||||
@ -1428,6 +1431,12 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
|
|||||||
prefetch(skb->data - NET_IP_ALIGN);
|
prefetch(skb->data - NET_IP_ALIGN);
|
||||||
skb_put(skb, pkt_len - 4);
|
skb_put(skb, pkt_len - 4);
|
||||||
data = skb->data;
|
data = skb->data;
|
||||||
|
|
||||||
|
#if !defined(CONFIG_M5272)
|
||||||
|
if (fep->quirks & FEC_QUIRK_HAS_RACC)
|
||||||
|
data = skb_pull_inline(skb, 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!is_copybreak && need_swap)
|
if (!is_copybreak && need_swap)
|
||||||
swap_buffer(data, pkt_len);
|
swap_buffer(data, pkt_len);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user