From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by yocto-www.yoctoproject.org (Postfix, from userid 118) id B8FE0E00C15; Fri, 23 Sep 2016 18:56:12 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on yocto-www.yoctoproject.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-HAM-Report: * -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low * trust * [68.230.241.23 listed in list.dnswl.org] * -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% * [score: 0.0000] X-Greylist: delayed 567 seconds by postgrey-1.32 at yocto-www; Fri, 23 Sep 2016 18:56:08 PDT Received: from fed1rmwml214.cox.net (fed1wml20.cox.net [68.230.241.23]) by yocto-www.yoctoproject.org (Postfix) with ESMTP id 623B4E007D3 for ; Fri, 23 Sep 2016 18:56:08 -0700 (PDT) Received: from fed1rmimpo110.cox.net ([68.230.241.159]) by fed1rmfepo202.cox.net (InterMail vM.8.01.05.28 201-2260-151-171-20160122) with ESMTP id <20160924014640.NTCW3827.fed1rmfepo202.cox.net@fed1rmimpo110.cox.net> for ; Fri, 23 Sep 2016 21:46:40 -0400 Received: from localhost.localdomain ([98.165.110.135]) by fed1rmimpo110.cox.net with cox id nDmd1t0032vKKqy01DmeYt; Fri, 23 Sep 2016 21:46:39 -0400 X-CT-Class: Clean X-CT-Score: 0.00 X-CT-RefID: str=0001.0A090203.57E5DAFF.0013, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CT-Spam: 0 X-Authority-Analysis: v=2.1 cv=O5WZxEJW c=1 sm=1 tr=0 a=lUT2YnrgGFadNepMmbQZ7w==:117 a=lUT2YnrgGFadNepMmbQZ7w==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=gu6fZOg2AAAA:8 a=drOt6m5kAAAA:8 a=9_1hYV8uAAAA:8 a=FfqU7amqtEM7ArlxmHMA:9 a=iutagpSzGJbjVe4u:21 a=YKTqw2qyar0kZzk5:21 a=-FEs8UIgK8oA:10 a=NWVoK91CQyQA:10 a=2RSlZUUhi9gRBrsHwhhZ:22 a=RMMjzBEyIzXRtoq5n5K6:22 a=FKwbt-OhbrkoYuZlCyy7:22 X-CM-Score: 0.00 Authentication-Results: cox.net; auth=pass (CRAM-MD5) smtp.auth=eric.a.nelson@cox.net From: Eric Nelson To: meta-freescale@yoctoproject.org Date: Fri, 23 Sep 2016 18:44:25 -0700 Message-Id: <1474681465-9796-1-git-send-email-eric@nelint.com> X-Mailer: git-send-email 2.7.4 Cc: andrew@lunn.ch, linux@arm.linux.org.uk, fugang.duan@nxp.com, otavio@ossystems.com.br Subject: [PATCH][linux-fslc][4.1-1.0.x-imx] net: fec: support RRACC_SHIFT16 to align IP header X-BeenThere: meta-freescale@yoctoproject.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Usage and development list for the meta-fsl-* layers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 Sep 2016 01:56:12 -0000 The i.MX6 UL and DQLS variants all support shifting the data payload of received packets by 16-bits, which aligns the IP header on a longword 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) With this patch, I am still seeing some alignment faults, but on the order of 10 after a 100MiB transfer instead of the 72k shown above. 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/?h=fec-testing&id=70d8a8a Signed-off-by: Eric Nelson --- I've only tested this patch on i.MX6UL at the moment, an encourage others using 4.1.x to try it out. I did look at the RM for the i.MX6SX and updates will be needed for that machine because the bit appears to be in a different location. Note that there are lots of other patches in Russell's tree that deserve some effort in bringing up-stream and I encourage others to make use of his work. drivers/net/ethernet/freescale/fec.h | 4 ++++ drivers/net/ethernet/freescale/fec_main.c | 36 +++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 65a3cd3..5ed0a5c 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -436,6 +436,7 @@ struct bufdesc_ex { #define FEC_QUIRK_SINGLE_MDIO (1 << 11) /* Controller supports RACC register */ #define FEC_QUIRK_HAS_RACC (1 << 12) + /* * i.MX6Q/DL ENET cannot wake up system in wait mode because ENET tx & rx * interrupt signal don't connect to GPC. So use pm qos to avoid cpu enter @@ -443,6 +444,9 @@ struct bufdesc_ex { */ #define FEC_QUIRK_BUG_WAITMODE (1 << 13) +/* Controller has ability to offset rx packets */ +#define FEC_QUIRK_RX_SHIFT16 (1 << 14) + struct fec_enet_stop_mode { struct regmap *gpr; u8 req_gpr; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 0f9ed22..a58d5d0 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -103,7 +103,8 @@ static struct platform_device_id fec_devtype[] = { .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 | - FEC_QUIRK_HAS_RACC | FEC_QUIRK_BUG_WAITMODE, + FEC_QUIRK_HAS_RACC | FEC_QUIRK_BUG_WAITMODE | + FEC_QUIRK_RX_SHIFT16, }, { .name = "mvf600-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC, @@ -118,7 +119,8 @@ static struct platform_device_id fec_devtype[] = { .name = "imx6ul-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | - FEC_QUIRK_HAS_VLAN, + FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_RACC | + FEC_QUIRK_RX_SHIFT16, }, { /* sentinel */ } @@ -180,6 +182,7 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); /* FEC receive acceleration */ #define FEC_RACC_IPDIS (1 << 1) #define FEC_RACC_PRODIS (1 << 2) +#define FEC_RACC_SHIFT16 BIT(7) #define FEC_RACC_OPTIONS (FEC_RACC_IPDIS | FEC_RACC_PRODIS) /* @@ -985,9 +988,11 @@ fec_restart(struct net_device *ndev) #if !defined(CONFIG_M5272) if (fep->quirks & FEC_QUIRK_HAS_RACC) { - /* set RX checksum */ val = readl(fep->hwp + FEC_RACC); + if (fep->quirks & FEC_QUIRK_RX_SHIFT16) + val |= FEC_RACC_SHIFT16; if (fep->csum_flags & FLAG_RX_CSUM_ENABLED) + /* set RX checksum */ val |= FEC_RACC_OPTIONS; else val &= ~FEC_RACC_OPTIONS; @@ -1387,6 +1392,7 @@ static bool fec_enet_copybreak(struct net_device *ndev, struct sk_buff **skb, { struct fec_enet_private *fep = netdev_priv(ndev); struct sk_buff *new_skb; + unsigned char *data = (*skb)->data; if (length > fep->rx_copybreak) return false; @@ -1395,13 +1401,25 @@ static bool fec_enet_copybreak(struct net_device *ndev, struct sk_buff **skb, if (!new_skb) return false; +#ifndef CONFIG_M5272 + /* + * If we have enabled this feature, we need to discard + * the two bytes at the beginning of the packet before + * copying it. + */ + if (fep->quirks & FEC_QUIRK_RX_SHIFT16) { + length -= 2; + data += 2; + } +#endif + dma_sync_single_for_cpu(&fep->pdev->dev, bdp->cbd_bufaddr, FEC_ENET_RX_FRSIZE - fep->rx_align, DMA_FROM_DEVICE); if (!swap) - memcpy(new_skb->data, (*skb)->data, length); + memcpy(new_skb->data, data, length); else - swap_buffer2(new_skb->data, (*skb)->data, length); + swap_buffer2(new_skb->data, data, length); *skb = new_skb; return true; @@ -1420,7 +1438,6 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) struct bufdesc *bdp; unsigned short status; struct sk_buff *skb_new = NULL; - struct sk_buff *skb; ushort pkt_len; __u8 *data; int pkt_received = 0; @@ -1443,6 +1460,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) bdp = rxq->cur_rx; while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { + struct sk_buff *skb; if (pkt_received >= budget) break; @@ -1504,6 +1522,12 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) prefetch(skb->data - NET_IP_ALIGN); skb_put(skb, pkt_len - 4); data = skb->data; + +#if !defined(CONFIG_M5272) + if (!is_copybreak && (fep->quirks & FEC_QUIRK_RX_SHIFT16)) + data = skb_pull_inline(skb, 2); +#endif + if (!is_copybreak && need_swap) swap_buffer(data, pkt_len); -- 2.7.4