If HW is Receive-Side-Coalescing capable, it cannot add dummy bytes at the start of IP packets. Alignment (ie number of dummy bytes) is configured using the RBOF field inside the NCFGR register. On the software side, the skb_reserve(skb, NET_IP_ALIGN) call must only be done if those dummy bytes are added by the hardware; notice the skb_reserve() is done AFTER writing the address to the device. We cannot do the skb_reserve() call BEFORE writing the address because the address field ignores the low 2/3 bits. Conclusion: in some cases, we risk not being able to respect the NET_IP_ALIGN value (which is picked based on unaligned CPU access performance). Current hardware (assuming it is working) falls in either category: - RSC-incapable or, - RSC-capable and NET_IP_ALIGN=0 (arm64/powerpc/x86). Fixes: 4df95131ea80 ("net/macb: change RX path for GEM") Signed-off-by: Théo Lebrun --- drivers/net/ethernet/cadence/macb.h | 3 +++ drivers/net/ethernet/cadence/macb_main.c | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index a7e845fee4b3a2e3d14abb49abdbaf3e8e6ea02b..a773d640d4738f158649e225ae4257164a6ef809 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -527,6 +527,8 @@ /* Bitfields in DCFG6. */ #define GEM_PBUF_LSO_OFFSET 27 #define GEM_PBUF_LSO_SIZE 1 +#define GEM_PBUF_RSC_OFFSET 26 +#define GEM_PBUF_RSC_SIZE 1 #define GEM_PBUF_CUTTHRU_OFFSET 25 #define GEM_PBUF_CUTTHRU_SIZE 1 #define GEM_DAW64_OFFSET 23 @@ -737,6 +739,7 @@ #define MACB_CAPS_MIIONRGMII 0x00000200 #define MACB_CAPS_NEED_TSUCLK 0x00000400 #define MACB_CAPS_QUEUE_DISABLE 0x00000800 +#define MACB_CAPS_RSC 0x00001000 #define MACB_CAPS_PCS 0x01000000 #define MACB_CAPS_HIGH_SPEED 0x02000000 #define MACB_CAPS_CLK_HW_CHG 0x04000000 diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index aa0b5aea48888eb2d1aa3edef45c804ae519f70d..1e19ebcaf3810ca87729bad0ef0e13db49c548e4 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -1332,8 +1332,18 @@ static void gem_rx_refill(struct macb_queue *queue) dma_wmb(); macb_set_addr(bp, desc, paddr); - /* properly align Ethernet header */ - skb_reserve(skb, NET_IP_ALIGN); + /* Properly align Ethernet header. + * + * Hardware can add dummy bytes if asked using the RBOF + * field inside the NCFGR register. That feature isn't + * available if hardware is RSC capable. + * + * We cannot fallback to doing the 2-byte shift before + * DMA mapping because the address field does not allow + * setting the low 2 (or 3 if DMA) bits. + */ + if (!(bp->caps & MACB_CAPS_RSC)) + skb_reserve(skb, NET_IP_ALIGN); } else { desc->ctrl = 0; dma_wmb(); @@ -2814,7 +2824,9 @@ static void macb_init_hw(struct macb *bp) macb_set_hwaddr(bp); config = macb_mdc_clk_div(bp); - config |= MACB_BF(RBOF, NET_IP_ALIGN); /* Make eth data aligned */ + /* Make eth data aligned. If RSC capable, that offset is ignored by HW. */ + if (!(bp->caps & MACB_CAPS_RSC)) + config |= MACB_BF(RBOF, NET_IP_ALIGN); config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ if (bp->caps & MACB_CAPS_JUMBO) config |= MACB_BIT(JFRAME); /* Enable jumbo frames */ @@ -4139,6 +4151,8 @@ static void macb_configure_caps(struct macb *bp, dcfg = gem_readl(bp, DCFG2); if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0) bp->caps |= MACB_CAPS_FIFO_MODE; + if (GEM_BFEXT(PBUF_RSC, gem_readl(bp, DCFG6))) + bp->caps |= MACB_CAPS_RSC; if (gem_has_ptp(bp)) { if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5))) dev_err(&bp->pdev->dev, -- 2.50.1