From patchwork Sun Mar 23 04:04:50 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Byungho An X-Patchwork-Id: 3878711 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id E0D79BF540 for ; Sun, 23 Mar 2014 04:06:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E105A202F8 for ; Sun, 23 Mar 2014 04:06:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A430B2017B for ; Sun, 23 Mar 2014 04:06:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751704AbaCWEGJ (ORCPT ); Sun, 23 Mar 2014 00:06:09 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:28644 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751288AbaCWEFr (ORCPT ); Sun, 23 Mar 2014 00:05:47 -0400 Received: from epcpsbgr4.samsung.com (u144.gpu120.samsung.co.kr [203.254.230.144]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N2V00C6AFC8VM90@mailout3.samsung.com>; Sun, 23 Mar 2014 13:04:56 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [203.254.230.50]) by epcpsbgr4.samsung.com (EPCPMTA) with SMTP id E6.3E.10364.86D5E235; Sun, 23 Mar 2014 13:04:56 +0900 (KST) X-AuditID: cbfee690-b7f266d00000287c-63-532e5d68a4cd Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id AA.9C.28157.76D5E235; Sun, 23 Mar 2014 13:04:56 +0900 (KST) Received: from VISITOR1LAB ([105.128.34.229]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N2V00G3DFBY4650@mmp2.samsung.com>; Sun, 23 Mar 2014 13:04:55 +0900 (KST) From: Byungho An To: netdev@vger.kernel.org, linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org Cc: 'David Miller' , 'GIRISH K S' , 'SIVAREDDY KALLAM' , 'Vipul Chandrakant' , 'Ilho Lee' Subject: [PATCH V12 5/7] net: sxgbe: add Checksum offload support for Samsung sxgbe Date: Sat, 22 Mar 2014 21:04:50 -0700 Message-id: <009001cf464d$0b886cf0$229946d0$@samsung.com> MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-index: Ac9GTLC+3ab0V7UmS6enjeoufwHu5g== Content-language: en-us X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrKIsWRmVeSWpSXmKPExsVy+t8zI92MWL1gg7b1HBZzzrewWMw/co7V 4ui/hYwW84/uYLKYcX4fk8WxBWIWK5q2MlpsW3CB2YHDY8vKm0wefVtWMXp83iQXwBzFZZOS mpNZllqkb5fAldH0SL+g06zi4+rlrA2Mx3W6GDk5JARMJBa3b2SFsMUkLtxbz9bFyMUhJLCM UaJp0QNGmKJlvVcZIRLTGSWu/uiCcv4ySly7u4AFpIpNQE2ieeZlNhBbRCBaYseRiWCjmAWu MUps+/0YrEhYIFRiyfddTCA2i4CqxMSZC5hBbF4BS4k/N65D2YISPybfA6tnFtCSWL/zOBOE LS+xec1bZoiTFCR2nH3NCLFMT2Lq3DdsEDXiEpMePGQHWSwhcIxdYkbnLTaIZQIS3yYfAhrK AZSQldh0AGqOpMTBFTdYJjCKzUKyehaS1bOQrJ6FZMUCRpZVjKKpBckFxUnpRSZ6xYm5xaV5 6XrJ+bmbGCFROGEH470D1ocYk4HWT2SWEk3OB0ZxXkm8obGZkYWpiamxkbmlGWnCSuK8ao+S goQE0hNLUrNTUwtSi+KLSnNSiw8xMnFwSjUwmrw6KtbTUau+4sPX95b5a4W2XHqY+pplUXv6 2hinJSe2XL/1Z+GBzZKRkZdrm/+r1NybtDVk0bq6F3I5Qmp29yu8mBm85pQ8mP+ZY6t/U673 Z+/MSuFHzjf332j3utL95O5EhwDZr4ePdRS0vFeXO/z69/NX6ycd1ypS0Mve/Xn5hczTob6G r5VYijMSDbWYi4oTAXEAry3YAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrEKsWRmVeSWpSXmKPExsVy+t9jQd2MWL1ggzldzBZzzrewWMw/co7V 4ui/hYwW84/uYLKYcX4fk8WxBWIWK5q2MlpsW3CB2YHDY8vKm0wefVtWMXp83iQXwBzVwGiT kZqYklqkkJqXnJ+SmZduq+QdHO8cb2pmYKhraGlhrqSQl5ibaqvk4hOg65aZA3SBkkJZYk4p UCggsbhYSd8O04TQEDddC5jGCF3fkCC4HiMDNJCwjjGj6ZF+QadZxcfVy1kbGI/rdDFyckgI mEgs673KCGGLSVy4t56ti5GLQ0hgOqPE1R9djBDOX0aJa3cXsIBUsQmoSTTPvMwGYosIREvs ODIRrINZ4BqjxLbfj8GKhAVCJZZ838UEYrMIqEpMnLmAGcTmFbCU+HPjOpQtKPFj8j2wemYB LYn1O48zQdjyEpvXvGWGOElBYsfZ14wQy/Qkps59wwZRIy4x6cFD9gmMArOQjJqFZNQsJKNm IWlZwMiyilE0tSC5oDgpPddIrzgxt7g0L10vOT93EyM4xp9J72Bc1WBxiFGAg1GJh7fgg26w EGtiWXFl7iFGCQ5mJRFeBl29YCHelMTKqtSi/Pii0pzU4kOMyUCfTmSWEk3OB6afvJJ4Q2MT MyNLIzMLIxNzc9KElcR5D7ZaBwoJpCeWpGanphakFsFsYeLglGpgjFj1cBPLl9iHAukP2X9V lFkvyBZQXhzYXrdtUURczbY1Ny0mc2Q1vulYqdofbvVut5lJwbsuD7vHp4OLttRvvOBh1+zo wNd5Yk/x3WNzlpk99tQ1u3a7YYrn1gq1f7M7/l5d+2DjlYTOJccdw90mfg3/c53PoyzptXjK yaRT+1+kys29cHpWmBJLcUaioRZzUXEiAI0pd+E1AwAA DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Vipul Pandya This patch adds TX and RX checksum offload support. Signed-off-by: Vipul Pandya Neatening-by: Joe Perches Signed-off-by: Byungho An --- drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h | 5 +++ drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c | 20 +++++++++ drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h | 2 +- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 46 ++++++++++++++++----- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h index 58e1ace..36a72a3 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h @@ -337,6 +337,10 @@ struct sxgbe_core_ops { void (*set_eee_timer)(void __iomem *ioaddr, const int ls, const int tw); void (*set_eee_pls)(void __iomem *ioaddr, const int link); + + /* Enable disable checksum offload operations */ + void (*enable_rx_csum)(void __iomem *ioaddr); + void (*disable_rx_csum)(void __iomem *ioaddr); }; const struct sxgbe_core_ops *sxgbe_get_core_ops(void); @@ -449,6 +453,7 @@ struct sxgbe_priv_data { struct sxgbe_ops *hw; /* sxgbe specific ops */ int no_csum_insertion; int irq; + int rxcsum_insertion; spinlock_t stats_lock; /* lock for tx/rx statatics */ struct phy_device *phydev; diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c index 0164790..66d4a74 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c @@ -218,6 +218,24 @@ static void sxgbe_set_eee_timer(void __iomem *ioaddr, writel(value, ioaddr + SXGBE_CORE_LPI_TIMER_CTRL); } +static void sxgbe_enable_rx_csum(void __iomem *ioaddr) +{ + u32 ctrl; + + ctrl = readl(ioaddr + SXGBE_CORE_RX_CONFIG_REG); + ctrl |= SXGBE_RX_CSUMOFFLOAD_ENABLE; + writel(ctrl, ioaddr + SXGBE_CORE_RX_CONFIG_REG); +} + +static void sxgbe_disable_rx_csum(void __iomem *ioaddr) +{ + u32 ctrl; + + ctrl = readl(ioaddr + SXGBE_CORE_RX_CONFIG_REG); + ctrl &= ~SXGBE_RX_CSUMOFFLOAD_ENABLE; + writel(ctrl, ioaddr + SXGBE_CORE_RX_CONFIG_REG); +} + const struct sxgbe_core_ops core_ops = { .core_init = sxgbe_core_init, .dump_regs = sxgbe_core_dump_regs, @@ -234,6 +252,8 @@ const struct sxgbe_core_ops core_ops = { .reset_eee_mode = sxgbe_reset_eee_mode, .set_eee_timer = sxgbe_set_eee_timer, .set_eee_pls = sxgbe_set_eee_pls, + .enable_rx_csum = sxgbe_enable_rx_csum, + .disable_rx_csum = sxgbe_disable_rx_csum, }; const struct sxgbe_core_ops *sxgbe_get_core_ops(void) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h index 6d44b9f..838cb9f 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h @@ -113,7 +113,7 @@ struct sxgbe_rx_norm_desc { /* WB RDES3 */ u32 pkt_len:14; u32 rdes3_reserved:1; - u32 err_summary:15; + u32 err_summary:1; u32 err_l2_type:4; u32 layer34_pkt_type:4; u32 no_coagulation_pkt:1; diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index c44464d..e433969 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -1252,6 +1252,7 @@ void sxgbe_tso_prepare(struct sxgbe_priv_data *priv, static netdev_tx_t sxgbe_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned int entry, frag_num; + int cksum_flag = 0; struct netdev_queue *dev_txq; unsigned txq_index = skb_get_queue_mapping(skb); struct sxgbe_priv_data *priv = netdev_priv(dev); @@ -1332,7 +1333,7 @@ static netdev_tx_t sxgbe_xmit(struct sk_buff *skb, struct net_device *dev) __func__); priv->hw->desc->prepare_tx_desc(tx_desc, 1, no_pagedlen, - no_pagedlen, 0); + no_pagedlen, cksum_flag); } } @@ -1350,7 +1351,7 @@ static netdev_tx_t sxgbe_xmit(struct sk_buff *skb, struct net_device *dev) /* prepare the descriptor */ priv->hw->desc->prepare_tx_desc(tx_desc, 0, len, - len, 0); + len, cksum_flag); /* memory barrier to flush descriptor */ wmb(); @@ -1471,6 +1472,8 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit) unsigned int entry = priv->rxq[qnum]->cur_rx; unsigned int next_entry = 0; unsigned int count = 0; + int checksum; + int status; while (count < limit) { struct sxgbe_rx_norm_desc *p; @@ -1487,7 +1490,18 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit) next_entry = (++priv->rxq[qnum]->cur_rx) % rxsize; prefetch(priv->rxq[qnum]->dma_rx + next_entry); - /*TO DO read the status of the incoming frame */ + /* Read the status of the incoming frame and also get checksum + * value based on whether it is enabled in SXGBE hardware or + * not. + */ + status = priv->hw->desc->rx_wbstatus(p, &priv->xstats, + &checksum); + if (unlikely(status < 0)) { + entry = next_entry; + continue; + } + if (unlikely(!priv->rxcsum_insertion)) + checksum = CHECKSUM_NONE; skb = priv->rxq[qnum]->rx_skbuff[entry]; @@ -1501,7 +1515,11 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit) skb_put(skb, frame_len); - netif_receive_skb(skb); + skb->ip_summed = checksum; + if (checksum == CHECKSUM_NONE) + netif_receive_skb(skb); + else + napi_gro_receive(&priv->napi, skb); entry = next_entry; } @@ -1748,15 +1766,15 @@ static int sxgbe_set_features(struct net_device *dev, { struct sxgbe_priv_data *priv = netdev_priv(dev); netdev_features_t changed = dev->features ^ features; - u32 ctrl; if (changed & NETIF_F_RXCSUM) { - ctrl = readl(priv->ioaddr + SXGBE_CORE_RX_CONFIG_REG); - if (features & NETIF_F_RXCSUM) - ctrl |= SXGBE_RX_CSUMOFFLOAD_ENABLE; - else - ctrl &= ~SXGBE_RX_CSUMOFFLOAD_ENABLE; - writel(ctrl, priv->ioaddr + SXGBE_CORE_RX_CONFIG_REG); + if (features & NETIF_F_RXCSUM) { + priv->hw->mac->enable_rx_csum(priv->ioaddr); + priv->rxcsum_insertion = true; + } else { + priv->hw->mac->disable_rx_csum(priv->ioaddr); + priv->rxcsum_insertion = false; + } } return 0; @@ -2113,6 +2131,12 @@ struct sxgbe_priv_data *sxgbe_drv_probe(struct device *device, } } + /* Enable Rx checksum offload */ + if (priv->hw_cap.rx_csum_offload) { + priv->hw->mac->enable_rx_csum(priv->ioaddr); + priv->rxcsum_insertion = true; + } + /* Rx Watchdog is available, enable depend on platform data */ if (!priv->plat->riwt_off) { priv->use_riwt = 1;