From patchwork Thu Sep 24 15:00:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Madalin Bucur X-Patchwork-Id: 522392 X-Patchwork-Delegate: scottwood@freescale.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 57967140281 for ; Fri, 25 Sep 2015 01:29:03 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id EE9B41A2E1C for ; Fri, 25 Sep 2015 01:29:02 +1000 (AEST) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from na01-bl2-obe.outbound.protection.outlook.com (mail-bl2on0101.outbound.protection.outlook.com [65.55.169.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 33BDC1A0E5D for ; Fri, 25 Sep 2015 01:19:03 +1000 (AEST) Received: from BLUPR0301CA0022.namprd03.prod.outlook.com (10.162.113.160) by BN3PR03MB1478.namprd03.prod.outlook.com (10.163.35.141) with Microsoft SMTP Server (TLS) id 15.1.274.16; Thu, 24 Sep 2015 15:03:03 +0000 Received: from BL2FFO11OLC003.protection.gbl (2a01:111:f400:7c09::172) by BLUPR0301CA0022.outlook.office365.com (2a01:111:e400:5259::32) with Microsoft SMTP Server (TLS) id 15.1.280.20 via Frontend Transport; Thu, 24 Sep 2015 15:03:03 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; freescale.mail.onmicrosoft.com; dmarc=none action=none header.from=freescale.com; Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Received: from az84smr01.freescale.net (192.88.158.2) by BL2FFO11OLC003.mail.protection.outlook.com (10.173.161.187) with Microsoft SMTP Server (TLS) id 15.1.274.4 via Frontend Transport; Thu, 24 Sep 2015 15:02:54 +0000 Received: from fsr-fed1764-003.ea.freescale.net (fsr-fed1764-003.ea.freescale.net [10.171.73.45]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id t8OF2Fkq018660; Thu, 24 Sep 2015 08:02:45 -0700 From: Madalin Bucur To: Subject: [v3 6/8] dpaa_eth: add ethtool statistics Date: Thu, 24 Sep 2015 18:00:17 +0300 Message-ID: <1443106819-5549-7-git-send-email-madalin.bucur@freescale.com> X-Mailer: git-send-email 1.8.2.3 In-Reply-To: <1443106819-5549-1-git-send-email-madalin.bucur@freescale.com> References: <1443106819-5549-1-git-send-email-madalin.bucur@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11OLC003; 1:e7EyaAAvQwYJ1kME1gSkPBDxPEgt8iAgaf9dFppYCPzupR97CFyDuV3cRbZhp/D637Onvm4leULO4EiDq2jsWzlgLTH3Ke5ksw1H/yaAZXzKC5fwkXXgwZwXDcgaZKEnUHx8n3a8c3S2wUMQBTDqktEpLlmhuT2AxajZAJabnhbx4aB4nqNB5WVb5D4ioxMcBQCF5+2jfjlLC0LUrKTZRJ69Dur9GhV4gq8YVjjJQMV0lB5d2/9OZlukSYGQDXVEv5SO0DCsHg7KTFAEDZZycjCH+QfgwuqiIgZ2GmCQvfZpH1t9FrnZfeR35m7VuOlMipC9AXWsW2UYW14FwpzwvZLc3TmJT4cJLbgvWwJIHRNBYX7DC0F7Umk3ikdAxWHODddx+upaJJRvj0mmd/Ua6g== X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(2980300002)(1109001)(1110001)(339900001)(189002)(199003)(50986999)(86362001)(77096005)(53806999)(85426001)(575784001)(68736005)(87936001)(46102003)(76176999)(5003940100001)(107886002)(5001960100002)(189998001)(110136002)(106466001)(105606002)(4001540100001)(81156007)(5001830100001)(229853001)(11100500001)(69596002)(50466002)(19580405001)(47776003)(104016004)(19580395003)(64706001)(6806005)(2950100001)(62966003)(50226001)(5007970100001)(77156002)(2351001)(43066003)(33646002)(36756003)(97736004)(5001860100001)(48376002)(4001430100001); DIR:OUT; SFP:1102; SCL:1; SRVR:BN3PR03MB1478; H:az84smr01.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB1478; 2:RYC+xOE6XoVmQBn71XEGeimK1nLTuNFY8LbMhvL36wqV76LOc7LYsbmkb3C+P0msh6spAxT0+tiNh/4oNUe1OPWqJpBbl8OzyNnm/NujQntgDYFdws7kGSsK1xJTqatLQeAMEL5cgfuBarVH2OErIZfUiRQJG2d9RbxL3gDK5aY=; 3:RAiMUqYgT3aEsg4DBkfEIMhbWzNfJi/Q+64OEIigLBDJFe9GNZUxo775JAAjT51t9TlNxIsu5zQ8IMqvW/wanUxDFSf6bbJXRpEFbCU4J9PzcQViTisvQqk9fs/bbDEtuDYilAI+Gxmn+cn4VDUso/kksfaINyB7CtXsiub+DPuqBASsB/PVX/pISg7/CHrMed2ZXz+HvfsEWxyTteo1ceWxdsqB6ilb0+/Px5DrufM=; 25:AMKBZ8gC6BLkN64PU4CDkj7sVMSCqxztjDXC02hUODmg55NpHzA7rNwhFxhQA7OsSm4LkaOMwLKu5IzGhe0UBvpYmGD8RjMjWv7GyHP2+EvWP/CqhczW2Ch/Ljx/SGFNI7hubnxz1n19jClJ41mWRWsIpDhcFV2ki8xMtDmDP56dVEa1Y6Dj6Kmig0pWq0P6yRzOX/ByeVGcD2ydkN6LuUZVkqQXSNFhfRY+rSwIxn513Caf6EVLw8NtMH2WXYLzkjjCBlkYinEyuHq0stj0Bw== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN3PR03MB1478; X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB1478; 20:aRruGUOc7u/sBqfYTSo+emYcKtDmHE8NfOcL8MQgxakLldbfyk/kCcU+ecDYYZcraaC1J7rSkIDco549KzAVXur55+ux/LSkj0R3yK0r2Hq/7XmwXW5TeHKZUtZG/vKMg8DF9OtYmM/tF1QMn8l6FhO3776r6+tWpU0ywuu5QeeI9KkC3/TFqk7ytGkqL/UqEjT6tFdIloXNWPo7hOq24QsEaJH/ZQiQEZ1Oesmjh/klmhlJWHXnQuOqD4tySEySas91h5MpH+F3oIkNKlqT9P85hXzFpNH3vXT/64Kwm5GUkumh3Q1xxP+TcFqxFtsTA+6KlQOGhmkY8YFpAsyVeKTCN8mQjxA8mfc8wTA03Vo=; 4:u93S+ovMQUxR9ncXRf7vmym+7pqfafZvOZRO4dWf34vdXdKkPgYiaL2Jo0vMcNR2zNY4BUTiWtQin+XGAq9MDp/ZZtYRiADIDzlxKS0uwD62XaZFDxjB7KQcG3G+Ix8svlzZ7QJ8JwCZoyZwBlJPxt0UOXcAsk5v49NzkrYxLO/pcTD1ihEdL7c4WwqU0YjNN7pmy0x4S5cjPzEa1crZHH8q6MuvgYXN+rCqJPwhmkh6VB5aK6xT5rUKXUroHrzPy9iVcq2m1JFCZpPOvZYrUms+7atQJvEWNU56fNi3O44SJljNoTxEvQSn4Yg0y21M7VjH4yLDM/4HQSfVIXX1q26s+0zaraRre3y2OVpwYuM= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(8121501046)(5005006)(520078)(3002001); SRVR:BN3PR03MB1478; BCL:0; PCL:0; RULEID:; SRVR:BN3PR03MB1478; X-Forefront-PRVS: 070912876F X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN3PR03MB1478; 23:qsUlIFBGy/OvE18QZByOtgSlEAIAsi17jppSMIfzT?= =?us-ascii?Q?xh+DsSKvMJVzbW1eBfN0WWeWwEFmP26wHV7iQI2zPTYi/75NJSZPEUpid2ls?= =?us-ascii?Q?MBZJ2ylALbdYy+SEyb41C1X8SgRr7TX5tC5Aqu0uu+aUjb74tQxXDrsxD2mM?= =?us-ascii?Q?UiqwLwjU9ZbS/jlWO3RLgRMZosgROByUEM8a7bLV1S8POHWiy93KxMVnKfVj?= =?us-ascii?Q?wr8MHYehntFJQfmYlZ1+aVHGb3gt8IJv3AV8XOnJdCMi+JSQAK0h2cEQLiEu?= =?us-ascii?Q?8HsvLmQZhq8/G8+QgdQl4SJJFoETJOr0Z7ayKSNTzmTVPUaXL1BOR44jsvt9?= =?us-ascii?Q?oQhGLO41Bn84LRZ30c5i0AdCmqR2gWwSqu8fAHrqnwaygX/jVRZ5SjOZC3Gm?= =?us-ascii?Q?50hTzjepsxaQ41TLumtHw9l2dNUuAp26Pv8QsICgZXR4OFPH/vKluwwqS824?= =?us-ascii?Q?2hG+wCijldMZ5iI575d9ypb94wRc1mSRfapd1Xl3Usqm5erplugMOLTni7Ah?= =?us-ascii?Q?lUv4LP3bdhe2sEx5evuh0JkVc31DRW+dEK7hXuhxdWl+2P+FcWCjlUMnbbxI?= =?us-ascii?Q?xjpTIW9IGLNXW8Q30Zva6R80SMZuzlrIds7wCnWQRpkjqnQI0EioEdN9ZR35?= =?us-ascii?Q?twADDAee2tVF39mdIqmOSf27P7z7STfn3Kd6CmK8/CkTN6MROWTnE37a+Odw?= =?us-ascii?Q?ixli0QeCg1ePFUiIqCrq8fp+8foHuHlKTRXw5zooOt44OLtgBRKYr8RZ8alL?= =?us-ascii?Q?ViuVgRl1BDVHzUav3c2nxXry2tu/Bh4Jmr3d7zo9ZrIiHFSlU9+GIM7sXfFi?= =?us-ascii?Q?WAeuqn2JVpEu0oFzyd3clNIJQ4gmSwB3+1bpAVeZ7fXc+rtwF0o1JngMcH9v?= =?us-ascii?Q?CPkTBSmAAQxHP6LbrFotnv7Wu8f589OqfAB973qjbPrvU5mCGZ+WAqKHder2?= =?us-ascii?Q?Pug+hmAHJHQOJQahtGvc8HvSTbLYLwcE2ZO+voqyZ3ffZNnVz57aBy9qv7OY?= =?us-ascii?Q?fCbj79T8SWA22GSHx1ie1dD2r7AnUkSY671wIU5mbEgLruRZ2o+83aZogoMk?= =?us-ascii?Q?IpavCb42Xnp/CDOA7WVLO25ToZVKhRs2qpAZqZ2yfS3GBdINREfgNdTSxTiP?= =?us-ascii?Q?9iNXrajnlf66z7QI/2KZBfrFODBClq6MBAOhsU4DPJUYyEGZhGxwS/fmAufX?= =?us-ascii?Q?ys4rTQIrnLAerkOQ+riVcZOKVQx44zAcXK0Cw6ugfEeSLbLG/zFCBdzMvX6r?= =?us-ascii?Q?Hc1ZAiObJsGKzALlbSStfxYjAmJrOVVUUvUhvOSDAHXZ8jbLAZnhK23SeMXZ?= =?us-ascii?Q?7/pbr6ven1cijIawGQFT6NyAACGDCazQWXQzOaAYyd6?= X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB1478; 5:jdK49rcva2WyHn3TTRzbYIRWxC42L/25jTClaCDTRA9iKQcExdibff72csFDaeV0WEn5/Mtl0z4r62yhiBsNpT6ERGdCdTLgfxqvk7eqsYtJt/PPY7D53HSw9y1PmRMl/REGudNBhaSChKhXgzc6VQ==; 24:GK4EtBQfe4AN7yukgBmMpfniHLvHun5e87Wxtjd1P0XrO/V6eBnoQ2GkhzYKpS2YtKZ3KaWfSJtah1rAUDjAhoOwnWB5rtPbTOV6HQuD9fk=; 20:1Plkp3uLgDrR/xUVAtGzwx9aYPQCDMR5U1rjmtRzFNOGOkY/M0X6ODSEzFwvEjwxc5WZSjGqQJcCFhmLixzKLg== X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Sep 2015 15:02:54.9027 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR03MB1478 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: madalin.bucur@freescale.com Cc: pebolle@tiscali.nl, f.fainelli@gmail.com, roy.pledge@freescale.com, linux-kernel@vger.kernel.org, ppc@mindchasers.com, stsp@list.ru, igal.liberman@freescale.com, scottwood@freescale.com, joe@perches.com, Ioana Ciornei , linuxppc-dev@lists.ozlabs.org, davem@davemloft.net, Madalin Bucur Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Add a series of counters to be exported through ethtool: - add detailed counters for reception errors; - add detailed counters for QMan enqueue reject events; - count the number of fragmented skbs received from the stack; - count all frames received on the Tx confirmation path; - add congestion group statistics; - count the number of interrupts for each CPU. Signed-off-by: Ioana Ciornei Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 12 ++ drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 34 ++++ .../net/ethernet/freescale/dpaa/dpaa_eth_common.c | 40 ++++- .../net/ethernet/freescale/dpaa/dpaa_eth_common.h | 2 + drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c | 1 + drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 183 +++++++++++++++++++++ 6 files changed, 270 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index a04c0aa..d0d3d80 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -104,6 +104,15 @@ static void _dpa_rx_error(struct net_device *net_dev, percpu_priv->stats.rx_errors++; + if (fd->status & FM_FD_ERR_DMA) + percpu_priv->rx_errors.dme++; + if (fd->status & FM_FD_ERR_PHYSICAL) + percpu_priv->rx_errors.fpe++; + if (fd->status & FM_FD_ERR_SIZE) + percpu_priv->rx_errors.fse++; + if (fd->status & FM_FD_ERR_PRS_HDR_ERR) + percpu_priv->rx_errors.phe++; + dpa_fd_release(net_dev, fd); } @@ -167,6 +176,8 @@ static void _dpa_tx_conf(struct net_device *net_dev, percpu_priv->stats.tx_errors++; } + percpu_priv->tx_confirm++; + skb = _dpa_cleanup_tx_fd(priv, fd); dev_kfree_skb(skb); @@ -302,6 +313,7 @@ static void priv_ern(struct qman_portal *portal, percpu_priv->stats.tx_dropped++; percpu_priv->stats.tx_fifo_errors++; + count_ern(percpu_priv, msg); /* If we intended this buffer to go into the pool * when the FM was done, we need to put it in diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index 349e052..629ccb8 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h @@ -192,6 +192,25 @@ struct dpa_bp { void (*free_buf_cb)(void *addr); }; +struct dpa_rx_errors { + u64 dme; /* DMA Error */ + u64 fpe; /* Frame Physical Error */ + u64 fse; /* Frame Size Error */ + u64 phe; /* Header Error */ +}; + +/* Counters for QMan ERN frames - one counter per rejection code */ +struct dpa_ern_cnt { + u64 cg_tdrop; /* Congestion group taildrop */ + u64 wred; /* WRED congestion */ + u64 err_cond; /* Error condition */ + u64 early_window; /* Order restoration, frame too early */ + u64 late_window; /* Order restoration, frame too late */ + u64 fq_tdrop; /* FQ taildrop */ + u64 fq_retired; /* FQ is retired */ + u64 orp_zero; /* ORP disabled */ +}; + struct dpa_napi_portal { struct napi_struct napi; struct qman_portal *p; @@ -200,7 +219,13 @@ struct dpa_napi_portal { struct dpa_percpu_priv_s { struct net_device *net_dev; struct dpa_napi_portal *np; + u64 in_interrupt; + u64 tx_confirm; + /* fragmented (non-linear) skbuffs received from the stack */ + u64 tx_frag_skbuffs; struct rtnl_link_stats64 stats; + struct dpa_rx_errors rx_errors; + struct dpa_ern_cnt ern_cnt; }; struct dpa_priv_s { @@ -227,6 +252,14 @@ struct dpa_priv_s { * (and the same) congestion group. */ struct qman_cgr cgr; + /* If congested, when it began. Used for performance stats. */ + u32 congestion_start_jiffies; + /* Number of jiffies the Tx port was congested. */ + u32 congested_jiffies; + /* Counter for the number of times the CGR + * entered congestion state + */ + u32 cgr_congested_count; } cgr_data; /* Use a per-port CGR for ingress traffic. */ bool use_ingress_cgr; @@ -288,6 +321,7 @@ static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv, np->p = portal; napi_schedule(&np->napi); + percpu_priv->in_interrupt++; return 1; } } diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c index 2b95696..4947cb9 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.c @@ -751,10 +751,15 @@ static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr, struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr, struct dpa_priv_s, cgr_data.cgr); - if (congested) + if (congested) { + priv->cgr_data.congestion_start_jiffies = jiffies; netif_tx_stop_all_queues(priv->net_dev); - else + priv->cgr_data.cgr_congested_count++; + } else { + priv->cgr_data.congested_jiffies += + (jiffies - priv->cgr_data.congestion_start_jiffies); netif_tx_wake_all_queues(priv->net_dev); + } } int dpaa_eth_cgr_init(struct dpa_priv_s *priv) @@ -1252,6 +1257,37 @@ void dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd) cpu_relax(); } +void count_ern(struct dpa_percpu_priv_s *percpu_priv, + const struct qm_mr_entry *msg) +{ + switch (msg->ern.rc & QM_MR_RC_MASK) { + case QM_MR_RC_CGR_TAILDROP: + percpu_priv->ern_cnt.cg_tdrop++; + break; + case QM_MR_RC_WRED: + percpu_priv->ern_cnt.wred++; + break; + case QM_MR_RC_ERROR: + percpu_priv->ern_cnt.err_cond++; + break; + case QM_MR_RC_ORPWINDOW_EARLY: + percpu_priv->ern_cnt.early_window++; + break; + case QM_MR_RC_ORPWINDOW_LATE: + percpu_priv->ern_cnt.late_window++; + break; + case QM_MR_RC_FQ_TAILDROP: + percpu_priv->ern_cnt.fq_tdrop++; + break; + case QM_MR_RC_ORPWINDOW_RETIRED: + percpu_priv->ern_cnt.fq_retired++; + break; + case QM_MR_RC_ORP_ZERO: + percpu_priv->ern_cnt.orp_zero++; + break; + } +} + /* Turn on HW checksum computation for this outgoing frame. * If the current protocol is not something we support in this regard * (or if the stack has already computed the SW checksum), we do nothing. diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h index 160a018..262b9b4 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_common.h @@ -100,6 +100,8 @@ void dpaa_eth_init_ports(struct mac_device *mac_dev, struct device *dev); void dpa_release_sgt(struct qm_sg_entry *sgt); void dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd); +void count_ern(struct dpa_percpu_priv_s *percpu_priv, + const struct qm_mr_entry *msg); int dpa_enable_tx_csum(struct dpa_priv_s *priv, struct sk_buff *skb, struct qm_fd *fd, diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c index fd32691..a311244 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth_sg.c @@ -673,6 +673,7 @@ int dpa_tx(struct sk_buff *skb, struct net_device *net_dev) likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) { /* Just create a S/G fd based on the skb */ err = skb_to_sg_fd(priv, skb, &fd); + percpu_priv->tx_frag_skbuffs++; } else { /* If the egress skb contains more fragments than we support * we have no choice but to linearize it ourselves. diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c index fa8ba69..e218354 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c @@ -37,6 +37,43 @@ #include "mac.h" #include "dpaa_eth_common.h" +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = { + "interrupts", + "rx packets", + "tx packets", + "tx confirm", + "tx S/G", + "tx error", + "rx error", + "bp count" +}; + +static char dpa_stats_global[][ETH_GSTRING_LEN] = { + /* dpa rx errors */ + "rx dma error", + "rx frame physical error", + "rx frame size error", + "rx header error", + + /* demultiplexing errors */ + "qman cg_tdrop", + "qman wred", + "qman error cond", + "qman early window", + "qman late window", + "qman fq tdrop", + "qman fq retired", + "qman orp disabled", + + /* congestion related stats */ + "congestion time (ms)", + "entered congestion", + "congested (0/1)" +}; + +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu) +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global) + static int dpa_get_settings(struct net_device *net_dev, struct ethtool_cmd *et_cmd) { @@ -217,6 +254,149 @@ static int dpa_set_pauseparam(struct net_device *net_dev, return err; } +static int dpa_get_sset_count(struct net_device *net_dev, int type) +{ + unsigned int total_stats, num_stats; + + num_stats = num_online_cpus() + 1; + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN; + + switch (type) { + case ETH_SS_STATS: + return total_stats; + default: + return -EOPNOTSUPP; + } +} + +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus, + int crr_cpu, u64 bp_count, u64 *data) +{ + int num_values = num_cpus + 1; + int crr = 0; + + /* update current CPU's stats and also add them to the total values */ + data[crr * num_values + crr_cpu] = percpu_priv->in_interrupt; + data[crr++ * num_values + num_cpus] += percpu_priv->in_interrupt; + + data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_packets; + data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_packets; + + data[crr * num_values + crr_cpu] = percpu_priv->stats.tx_packets; + data[crr++ * num_values + num_cpus] += percpu_priv->stats.tx_packets; + + data[crr * num_values + crr_cpu] = percpu_priv->tx_confirm; + data[crr++ * num_values + num_cpus] += percpu_priv->tx_confirm; + + data[crr * num_values + crr_cpu] = percpu_priv->tx_frag_skbuffs; + data[crr++ * num_values + num_cpus] += percpu_priv->tx_frag_skbuffs; + + data[crr * num_values + crr_cpu] = percpu_priv->stats.tx_errors; + data[crr++ * num_values + num_cpus] += percpu_priv->stats.tx_errors; + + data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_errors; + data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_errors; + + data[crr * num_values + crr_cpu] = bp_count; + data[crr++ * num_values + num_cpus] += bp_count; +} + +static void dpa_get_ethtool_stats(struct net_device *net_dev, + struct ethtool_stats *stats, u64 *data) +{ + u64 bp_count, cg_time, cg_num, cg_status; + struct dpa_percpu_priv_s *percpu_priv; + struct qm_mcr_querycgr query_cgr; + struct dpa_rx_errors rx_errors; + struct dpa_ern_cnt ern_cnt; + struct dpa_priv_s *priv; + unsigned int num_cpus, offset; + struct dpa_bp *dpa_bp; + int total_stats, i; + + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS); + priv = netdev_priv(net_dev); + dpa_bp = priv->dpa_bp; + num_cpus = num_online_cpus(); + bp_count = 0; + + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors)); + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt)); + memset(data, 0, total_stats * sizeof(u64)); + + for_each_online_cpu(i) { + percpu_priv = per_cpu_ptr(priv->percpu_priv, i); + + if (dpa_bp->percpu_count) + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i)); + + rx_errors.dme += percpu_priv->rx_errors.dme; + rx_errors.fpe += percpu_priv->rx_errors.fpe; + rx_errors.fse += percpu_priv->rx_errors.fse; + rx_errors.phe += percpu_priv->rx_errors.phe; + + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop; + ern_cnt.wred += percpu_priv->ern_cnt.wred; + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond; + ern_cnt.early_window += percpu_priv->ern_cnt.early_window; + ern_cnt.late_window += percpu_priv->ern_cnt.late_window; + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop; + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired; + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero; + + copy_stats(percpu_priv, num_cpus, i, bp_count, data); + } + + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN; + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors)); + + offset += sizeof(struct dpa_rx_errors) / sizeof(u64); + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt)); + + /* gather congestion related counters */ + cg_num = 0; + cg_status = 0; + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies); + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) { + cg_num = priv->cgr_data.cgr_congested_count; + cg_status = query_cgr.cgr.cs; + + /* reset congestion stats (like QMan API does */ + priv->cgr_data.congested_jiffies = 0; + priv->cgr_data.cgr_congested_count = 0; + } + + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64); + data[offset++] = cg_time; + data[offset++] = cg_num; + data[offset++] = cg_status; +} + +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data) +{ + unsigned int i, j, num_cpus, size; + char string_cpu[ETH_GSTRING_LEN]; + u8 *strings; + + strings = data; + num_cpus = num_online_cpus(); + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN; + + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) { + for (j = 0; j < num_cpus; j++) { + snprintf(string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", + dpa_stats_percpu[i], j); + memcpy(strings, string_cpu, ETH_GSTRING_LEN); + strings += ETH_GSTRING_LEN; + } + snprintf(string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", + dpa_stats_percpu[i]); + memcpy(strings, string_cpu, ETH_GSTRING_LEN); + strings += ETH_GSTRING_LEN; + } + memcpy(strings, dpa_stats_global, size); +} + const struct ethtool_ops dpa_ethtool_ops = { .get_settings = dpa_get_settings, .set_settings = dpa_set_settings, @@ -227,4 +407,7 @@ const struct ethtool_ops dpa_ethtool_ops = { .get_pauseparam = dpa_get_pauseparam, .set_pauseparam = dpa_set_pauseparam, .get_link = ethtool_op_get_link, + .get_sset_count = dpa_get_sset_count, + .get_ethtool_stats = dpa_get_ethtool_stats, + .get_strings = dpa_get_strings, };