From patchwork Wed Mar 5 11:28:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Byungho An X-Patchwork-Id: 25753 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vc0-f198.google.com (mail-vc0-f198.google.com [209.85.220.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id E21F8203C3 for ; Wed, 5 Mar 2014 11:28:46 +0000 (UTC) Received: by mail-vc0-f198.google.com with SMTP id lf12sf1958852vcb.5 for ; Wed, 05 Mar 2014 03:28:46 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :mime-version:thread-index:dlp-filter:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe:content-type :content-transfer-encoding:content-language; bh=fabzbO6AhPOMUeSH8iJ/DtINjQexEPfx7JYrXvgSVHs=; b=fq5wDm5ISmuk6DgVV03fKRb5z3XZxrBPLrH8aU+wmVvMznuKawWOWJK8GGbohUqwjz HloHt/+Aen4q9iovKdidMOoWS84B7IaNFrsR2RmoRNdjFEV3Y0OlLGJA2OM62wLKtjOv KH5UvSbzRtpLW+48u1OepdtSR/T7ufDBgaIn/kkb9HMhbfzJtr6Cext2dsu/oEz4XwQy F1mmIeaVb1vvq3ykN15WKACPLo6wZl2lKox3KhleLLm7EAMVk9bnSwzA9lUwk6VxFEAH Q4LGCG2RPXR2sno6khZLB+iIa3FB6MrOtC61vevvSdI82scuAuH4RpOCkTAF1jzn1gMv CMRw== X-Gm-Message-State: ALoCoQkqLfDM5VwdfTk1MJYtDrV2Yap80S7itbiQM9XDBEUz3BuKoFZVJ0KPtAh3omtohAb6hYTN X-Received: by 10.59.7.2 with SMTP id cy2mr2421643ved.9.1394018926640; Wed, 05 Mar 2014 03:28:46 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.101.70 with SMTP id t64ls271839qge.1.gmail; Wed, 05 Mar 2014 03:28:46 -0800 (PST) X-Received: by 10.59.7.170 with SMTP id dd10mr46965ved.12.1394018926425; Wed, 05 Mar 2014 03:28:46 -0800 (PST) Received: from mail-vc0-f169.google.com (mail-vc0-f169.google.com [209.85.220.169]) by mx.google.com with ESMTPS id fi2si589479vdb.101.2014.03.05.03.28.46 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 05 Mar 2014 03:28:46 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.169 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.169; Received: by mail-vc0-f169.google.com with SMTP id hq11so868175vcb.14 for ; Wed, 05 Mar 2014 03:28:46 -0800 (PST) X-Received: by 10.58.211.8 with SMTP id my8mr59681vec.80.1394018926312; Wed, 05 Mar 2014 03:28:46 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.78.9 with SMTP id i9csp11202vck; Wed, 5 Mar 2014 03:28:45 -0800 (PST) X-Received: by 10.66.151.205 with SMTP id us13mr6063714pab.93.1394018924763; Wed, 05 Mar 2014 03:28:44 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j4si2194728pad.22.2014.03.05.03.28.44; Wed, 05 Mar 2014 03:28:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-samsung-soc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755552AbaCEL2h (ORCPT + 8 others); Wed, 5 Mar 2014 06:28:37 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:58294 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751704AbaCEL22 (ORCPT ); Wed, 5 Mar 2014 06:28:28 -0500 Received: from epcpsbgr1.samsung.com (u141.gpu120.samsung.co.kr [203.254.230.141]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N1Y00DY2NVDOJ60@mailout2.samsung.com>; Wed, 05 Mar 2014 20:28:25 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [203.254.230.50]) by epcpsbgr1.samsung.com (EPCPMTA) with SMTP id 03.A2.12635.95A07135; Wed, 05 Mar 2014 20:28:25 +0900 (KST) X-AuditID: cbfee68d-b7fcd6d00000315b-a9-53170a5911e8 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 52.30.28157.95A07135; Wed, 05 Mar 2014 20:28:25 +0900 (KST) Received: from DObh74an01 ([12.36.166.149]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N1Y0075NNVDKZ00@mmp1.samsung.com>; Wed, 05 Mar 2014 20:28:25 +0900 (KST) From: Byungho An To: netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org Cc: davem@davemloft.net, vipul.pandya@samsung.com, ilho215.lee@samsung.com Subject: [PATCH 4/7] net: xgmac: add Checksum offload support for Samsung xgmac Date: Wed, 05 Mar 2014 20:28:25 +0900 Message-id: <007e01cf3866$05db1fe0$11915fa0$%an@samsung.com> MIME-version: 1.0 X-Mailer: Microsoft Office Outlook 12.0 Thread-index: Ac84ZgW/EUdZUcCHRs2lBhdVwyhLSQ== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrHIsWRmVeSWpSXmKPExsVy+t8zI91ILvFgg455mhZXzx1jtJhzvoXF Yv6Rc6wWR/8tZLSYcX4fk8WxBWIW2xZcYHZg99iy8iaTR9+WVYwenzfJBTBHcdmkpOZklqUW 6dslcGU0XjnDWvA2oOLJ2znsDYwTnboYOTkkBEwk1r87wgJhi0lcuLeerYuRi0NIYBmjRMuF BSwwRas6bzNCJBYxSsw5PgPK+c0o8eHkY2aQKjYBNYnmmZeB2jk4RASiJV71pIOEmQW8JNrO 7GEFsYUF/CWWbe5nBLFZBFQlZq/8C7aAV8BGovnzPSYIW1Dix+R7LBC9WhKbtzWxQtjyEpvX vGUGGS8hoC7x6K8uSFhEQE9iZ88tRogSEYl9L96BnSYhcIhdovHsfVaIXQIS3yYfYoHolZXY dIAZ4i9JiYMrbrBMYBSbhWTzLCSbZyHZPAvJigWMLKsYRVMLkguKk9KLDPWKE3OLS/PS9ZLz czcxQuKudwfj7QPWhxiTgdZPZJYSTc4Hxm1eSbyhsZmRhamJqbGRuaUZacJK4rxJD5OChATS E0tSs1NTC1KL4otKc1KLDzEycXBKNTBq/y2deTj1adQWwW8M1m37drU0iXzK7K7/GXCyrmjv fl2/7RuON2/YLDrp8vtYXdaZL1piJKyyp83d2sP+tbImU2anq4HR+XXrujI5o7zXvbX7Nflz x+HEXgN92fyDQQ/jLtVPDdD/ucZX/M+rzOaau0bnfrmWNB2ztLmxdvN2lrfflu4V3iGnxFKc kWioxVxUnAgAjmssTNECAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprNKsWRmVeSWpSXmKPExsVy+t9jAd1ILvFgg+93lS2unjvGaDHnfAuL xfwj51gtjv5byGgx4/w+JotjC8Qsti24wOzA7rFl5U0mj74tqxg9Pm+SC2COamC0yUhNTEkt UkjNS85PycxLt1XyDo53jjc1MzDUNbS0MFdSyEvMTbVVcvEJ0HXLzAFarqRQlphTChQKSCwu VtK3wzQhNMRN1wKmMULXNyQIrsfIAA0krGPMaLxyhrXgbUDFk7dz2BsYJzp1MXJySAiYSKzq vM0IYYtJXLi3nq2LkYtDSGARo8Sc4zMYIZzfjBIfTj5mBqliE1CTaJ55GaiKg0NEIFriVU86 SJhZwEui7cweVhBbWMBfYtnmfrChLAKqErNX/mUBsXkFbCSaP99jgrAFJX5MvscC0aslsXlb EyuELS+xec1bZpDxEgLqEo/+6oKERQT0JHb23GKEKBGR2PfiHeMERoFZSCbNQjJpFpJJs5C0 LGBkWcUomlqQXFCclJ5rpFecmFtcmpeul5yfu4kRHNXPpHcwrmqwOMQowMGoxMP7gkMsWIg1 say4MvcQowQHs5II7zEW8WAh3pTEyqrUovz4otKc1OJDjMlAj05klhJNzgcmnLySeENjEzMj SyMzCyMTc3PShJXEeQ+2WgcKCaQnlqRmp6YWpBbBbGHi4JRqYOTZkf2x/WH15iX2SxR5wl5+ 4+T9Nv0Le9Yf9Ug7Of1u7Slbuzrcpuyscj7jkyVdzrP/vS7bDJ6svhiT6kKPmY8VDF0+Bn7l SEyfx3x1hxdHy42OzzP5Tq79P5+teEK6cJAc372JO4VexRc29gXc1A3YICaQsf78w0LxTddE uNkS/2m6F2YJKLEUZyQaajEXFScCAF1LFY4uAwAA DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: bh74.an@samsung.com X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.169 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7bit Content-language: ko From: Vipul Pandya This patch adds TX and RX checksum offload support. Signed-off-by: Vipul Pandya Signed-off-by: Byungho An --- drivers/net/ethernet/samsung/xgmac_common.h | 6 +++- drivers/net/ethernet/samsung/xgmac_core.c | 20 ++++++++++++ drivers/net/ethernet/samsung/xgmac_desc.c | 29 +++++++++++++---- drivers/net/ethernet/samsung/xgmac_desc.h | 8 ++--- drivers/net/ethernet/samsung/xgmac_main.c | 46 ++++++++++++++++++++------- 5 files changed, 86 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/samsung/xgmac_common.h b/drivers/net/ethernet/samsung/xgmac_common.h index 6b7f1de..349cddc 100644 --- a/drivers/net/ethernet/samsung/xgmac_common.h +++ b/drivers/net/ethernet/samsung/xgmac_common.h @@ -351,6 +351,10 @@ struct xgmac_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 xgmac_core_ops *xgmac_get_core_ops(void); @@ -466,7 +470,7 @@ struct xgmac_priv_data { struct net_device *dev; struct device *device; struct xgmac_ops *hw;/* xgmac specific ops */ - int no_csum_insertion; + int rxcsum_insertion; spinlock_t lock; spinlock_t stats_lock; diff --git a/drivers/net/ethernet/samsung/xgmac_core.c b/drivers/net/ethernet/samsung/xgmac_core.c index ed475fa..43d093c 100644 --- a/drivers/net/ethernet/samsung/xgmac_core.c +++ b/drivers/net/ethernet/samsung/xgmac_core.c @@ -217,6 +217,24 @@ static void xgmac_set_eee_timer(void __iomem *ioaddr, writel(value, ioaddr + XGMAC_CORE_LPI_TIMER_CTRL); } +static void xgmac_enable_rx_csum(void __iomem *ioaddr) +{ + u32 ctrl; + + ctrl = readl(ioaddr + XGMAC_CORE_RX_CONFIG_REG); + ctrl |= XGMAC_RX_CSUMOFFLOAD_ENABLE; + writel(ctrl, ioaddr + XGMAC_CORE_RX_CONFIG_REG); +} + +static void xgmac_disable_rx_csum(void __iomem *ioaddr) +{ + u32 ctrl; + + ctrl = readl(ioaddr + XGMAC_CORE_RX_CONFIG_REG); + ctrl &= ~XGMAC_RX_CSUMOFFLOAD_ENABLE; + writel(ctrl, ioaddr + XGMAC_CORE_RX_CONFIG_REG); +} + const struct xgmac_core_ops core_ops = { .core_init = xgmac_core_init, .dump_regs = xgmac_core_dump_regs, @@ -233,6 +251,8 @@ const struct xgmac_core_ops core_ops = { .reset_eee_mode = xgmac_reset_eee_mode, .set_eee_timer = xgmac_set_eee_timer, .set_eee_pls = xgmac_set_eee_pls, + .enable_rx_csum = xgmac_enable_rx_csum, + .disable_rx_csum = xgmac_disable_rx_csum, }; const struct xgmac_core_ops *xgmac_get_core_ops(void) diff --git a/drivers/net/ethernet/samsung/xgmac_desc.c b/drivers/net/ethernet/samsung/xgmac_desc.c index 51b7e71..c5417de 100644 --- a/drivers/net/ethernet/samsung/xgmac_desc.c +++ b/drivers/net/ethernet/samsung/xgmac_desc.c @@ -37,13 +37,16 @@ static void xgmac_tx_desc_enable_tse(struct xgmac_tx_norm_desc *p, u8 is_tse, /* Assign buffer lengths for descriptor */ static void xgmac_prepare_tx_desc(struct xgmac_tx_norm_desc *p, u8 is_fd, - int buf1_len, int pkt_len) + int buf1_len, int pkt_len, int cksum) { p->tdes23.tx_rd_des23.first_desc = is_fd; p->tdes23.tx_rd_des23.buf1_size = buf1_len; p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.total_pkt_len = pkt_len; + if (cksum) + p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.cksum_ctl = + cic_full; } /* Set VLAN control information */ @@ -249,31 +252,40 @@ static int xgmac_get_rx_ld_status(struct xgmac_rx_norm_desc *p) /* Return the RX status looking at the WB fields */ -static void xgmac_rx_wbstatus(struct xgmac_rx_norm_desc *p, - struct xgmac_extra_stats *x) +static int xgmac_rx_wbstatus(struct xgmac_rx_norm_desc *p, + struct xgmac_extra_stats *x, int *checksum) { + int status = 0; + *checksum = CHECKSUM_UNNECESSARY; if (p->rdes23.rx_wb_des23.err_summary) { switch (p->rdes23.rx_wb_des23.err_l2_type) { case RX_GMII_ERR: + status = -EINVAL; x->rx_code_gmii_err++; break; case RX_WATCHDOG_ERR: + status = -EINVAL; x->rx_watchdog_err++; break; case RX_CRC_ERR: + status = -EINVAL; x->rx_crc_err++; break; case RX_GAINT_ERR: + status = -EINVAL; x->rx_gaint_pkt_err++; break; case RX_IP_HDR_ERR: + *checksum = CHECKSUM_NONE; x->ip_hdr_err++; break; case RX_PAYLOAD_ERR: + *checksum = CHECKSUM_NONE; x->ip_payload_err++; break; case RX_OVERFLOW_ERR: + status = -EINVAL; x->overflow_error++; break; default: @@ -366,12 +378,14 @@ static void xgmac_rx_wbstatus(struct xgmac_rx_norm_desc *p, if (p->rdes23.rx_wb_des23.vlan_filter_match) x->vlan_filter_match++; - if (p->rdes23.rx_wb_des23.sa_filter_fail) + if (p->rdes23.rx_wb_des23.sa_filter_fail) { + status = -EINVAL; x->sa_filter_fail++; - - if (p->rdes23.rx_wb_des23.da_filter_fail) + } + if (p->rdes23.rx_wb_des23.da_filter_fail) { + status = -EINVAL; x->da_filter_fail++; - + } if (p->rdes23.rx_wb_des23.hash_filter_pass) x->hash_filter_pass++; @@ -381,6 +395,7 @@ static void xgmac_rx_wbstatus(struct xgmac_rx_norm_desc *p, if (p->rdes23.rx_wb_des23.l4_filter_match) x->l4_filter_match++; + return status; } /* Get own bit of context descriptor */ diff --git a/drivers/net/ethernet/samsung/xgmac_desc.h b/drivers/net/ethernet/samsung/xgmac_desc.h index d9b80fc..028b505 100644 --- a/drivers/net/ethernet/samsung/xgmac_desc.h +++ b/drivers/net/ethernet/samsung/xgmac_desc.h @@ -113,7 +113,7 @@ struct xgmac_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; @@ -173,7 +173,7 @@ struct xgmac_desc_ops { /* Assign buffer lengths for descriptor */ void (*prepare_tx_desc)(struct xgmac_tx_norm_desc *p, u8 is_fd, - int buf1_len, int pkt_len); + int buf1_len, int pkt_len, int cksum); /* Set VLAN control information */ void (*tx_vlanctl_desc)(struct xgmac_tx_norm_desc *p, int vlan_ctl); @@ -273,8 +273,8 @@ struct xgmac_desc_ops { int (*get_rx_ld_status)(struct xgmac_rx_norm_desc *p); /* Return the reception status looking at the RDES1 */ - void (*rx_wbstatus)(struct xgmac_rx_norm_desc *p, - struct xgmac_extra_stats *x); + int (*rx_wbstatus)(struct xgmac_rx_norm_desc *p, + struct xgmac_extra_stats *x, int *checksum); /* Get own bit */ int (*get_rx_ctxt_owner)(struct xgmac_rx_ctxt_desc *p); diff --git a/drivers/net/ethernet/samsung/xgmac_main.c b/drivers/net/ethernet/samsung/xgmac_main.c index 6d14c81..d1f746a 100644 --- a/drivers/net/ethernet/samsung/xgmac_main.c +++ b/drivers/net/ethernet/samsung/xgmac_main.c @@ -1332,6 +1332,7 @@ void xgmac_tso_prepare(struct xgmac_priv_data *priv, static netdev_tx_t xgmac_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 xgmac_priv_data *priv = netdev_priv(dev); @@ -1403,7 +1404,7 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) , __func__); priv->hw->desc->prepare_tx_desc(tx_desc, 1, no_pagedlen, - no_pagedlen); + no_pagedlen, cksum_flag); } } @@ -1420,7 +1421,7 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev) /* prepare the descriptor */ priv->hw->desc->prepare_tx_desc(tx_desc, 0, len, - len); + len, cksum_flag); /* memory barrier to flush descriptor */ wmb(); @@ -1545,6 +1546,8 @@ static int xgmac_rx(struct xgmac_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 xgmac_rx_norm_desc *p; @@ -1561,7 +1564,18 @@ static int xgmac_rx(struct xgmac_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 XGMAC 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]; @@ -1577,7 +1591,11 @@ static int xgmac_rx(struct xgmac_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; } @@ -1808,15 +1826,15 @@ static int xgmac_set_features(struct net_device *dev, { struct xgmac_priv_data *priv = netdev_priv(dev); netdev_features_t changed = dev->features ^ features; - u32 ctrl; if (changed & NETIF_F_RXCSUM) { - ctrl = readl(priv->ioaddr + XGMAC_CORE_RX_CONFIG_REG); - if (features & NETIF_F_RXCSUM) - ctrl |= XGMAC_RX_CSUMOFFLOAD_ENABLE; - else - ctrl &= ~XGMAC_RX_CSUMOFFLOAD_ENABLE; - writel(ctrl, priv->ioaddr + XGMAC_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; @@ -2178,6 +2196,12 @@ struct xgmac_priv_data *xgmac_dvr_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;