From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966466AbcKOIns (ORCPT ); Tue, 15 Nov 2016 03:43:48 -0500 Received: from mail-cys01nam02on0055.outbound.protection.outlook.com ([104.47.37.55]:59904 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S965628AbcKOIlh (ORCPT ); Tue, 15 Nov 2016 03:41:37 -0500 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=nxp.com; infinera.com; dkim=none (message not signed) header.d=none;infinera.com; dmarc=fail action=none header.from=nxp.com; X-IncomingTopHeaderMarker: OriginalChecksum:;UpperCasedChecksum:;SizeAsReceived:877;Count:11 From: Madalin Bucur To: CC: , , , , , , , Subject: [PATCH net-next v8 4/9] dpaa_eth: add ethtool statistics Date: Tue, 15 Nov 2016 10:41:04 +0200 Message-ID: <1479199269-9748-5-git-send-email-madalin.bucur@nxp.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1479199269-9748-1-git-send-email-madalin.bucur@nxp.com> References: <1479199269-9748-1-git-send-email-madalin.bucur@nxp.com> Reply-To: X-IncomingHeaderCount: 11 X-EOPAttributedMessage: 0 X-Matching-Connectors: 131236728869205386;(91ab9b29-cfa4-454e-5278-08d120cd25b8);() X-Forefront-Antispam-Report: CIP:192.88.158.2;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(7916002)(2980300002)(1109001)(1110001)(336004)(339900001)(189002)(199003)(69596002)(48376002)(106466001)(626004)(2351001)(105606002)(77096005)(5660300001)(7846002)(86362001)(36756003)(356003)(104016004)(6666003)(110136003)(47776003)(305945005)(6916009)(2950100002)(43066003)(8676002)(2906002)(189998001)(85426001)(4326007)(87936001)(97736004)(50226002)(81156014)(81166006)(3450700001)(53806999)(68736007)(8936002)(5003940100001)(50986999)(76176999)(33646002)(50466002);DIR:OUT;SFP:1101;SCL:1;SRVR:DM5PR03MB2476;H:az84smr01.freescale.net;FPR:;SPF:Fail;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BN1BFFO11FD032;1:ryWuj+SuQ42MHYwcHHdw/geb6ej7tvN23CevpAxTfv7yMpeQ6odj+C7A1zp6PnyNyORIrIEHPrzpn0gL7fJ/daar1whZqPdUDLgT5C7bUUGoyw6s6r8Op3Aj0FLzY8B2GL2xsYLJitxwbzVv/ijloup7MDjX9NLepI2slDUQ6hHgvT1YSjS9PxlfmCkpLaTq85txXiLCll8mCReOv5BUs8cSlEiW/8I81+eO7WrrPeMUQxnnNKzYT2sT5z5AqpsP7Wbp+FvYuqMTZIc6oPdUfsIPtAaeRCkwFKQhc+vV151MQBZSfR384Ao5el6eVnrxmLTc9iO6j4/G4TAsie3FTZi4opCSpu/KCnNOMCRA3cFDgNHWQKXP8GXS3s9pkksFn9wTfVdSVwWmdc4t/+w5q52d12szfBjJK//fhxphzsfJDBUxXG86oAehKpkmy83mxATomBAVY3vHt4MSlLHS3mJI70QhuVlL149WbWSH0Yol45gbI9Ps6pzC55E9KZdc2Nc6GH2KO8rAbR5Q2gDOfjv2fdedRmS9+5+czLgf6LObNTtHDCCoiiuFO93yESVTa9mKqOw6YwuoRGVl0IJ7/mwmFdXCoHjhtR084VMfxwMZkhCYSbva7QosV9gircsl MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Exchange-Diagnostics: 1;DM5PR03MB2476;2:SWw+ikmT3o8kPKsVQhSr0gUiNL6OKwBc710hlH1AbWaMTgjtn3V+aiBHaebk38yi47tTFURRTfNVKoNjbFPp0baBx3IQhIS3SGjiUot6aOgGYc66MkXGEMdysh5S8mOxql9zfMLRHkJd6Qt4rADdm3bvDfImznuZ7sTo/WQbyX8=;3:9sBId4zf7bmcSr244SepaLbjjbm43LrIP4UvHvNn5lp7z8W639nkRU01psbV4zxmmigenCpijwcRE1hMeSYJfkiDpkGzFnX9nVavDFhCcKPT44PwoxYSBxtIX9ETXm3rZI1KLT0AIymK7nBfvDMKUGInu6XD2pPP7OcR0O9W4qWdIJJZavbyhc1yS9qtD1r5tWuVPgpi8ksn8aEIN5XE90vtUGQusZf2vdrks2dY14b4VbrRPNQ+4+INVARWWlD0CS/XVF/xmeT1G41/R1DnQw==;25:ibOS+0AzOvOTcWuwCHSvoGv7MBffkenPTaFtIbOmOAlh6zkBe1QocC2QHCaWWKIJq2El7I6qxRagVFP9qFsnFi0Qhgf3Y1kvXmym0obEEyNHFKRb9e33T8SMMXa/22vD/sds8Dg6dNV81Oj3Xov1Dbs0yxHe7bVzowvWUtfi737zZFaHkPmZ4mNa/jsHwr0QxPuGhNRzlTF2HSPeEkxYrotXe7ACtG8pb4QIFSkN+H4x/1gaJqurtbo5pdONQKQfWQ7nKwkVnydUMh8kfw8XSbGZagSxYQixQE9dL2/QGpTvjfoW9LV2nXCuAYwUlxm0Nf0EU7XWH+sqewD29z4VakvOrBrNi7d6BJrrH/9Lf/KLw7DC+3QcHNAVJ94Ftokb1ODqsnRfs3xoyE+OCeWL5MT2h4HI3nwHenH8h4FTDmQhkyC0tlHfu+Ku1y0SuRRpkz5Gb56aXg/8hcLpFS9CvQ== X-MS-Office365-Filtering-Correlation-Id: e4c99843-4973-420d-b58a-08d40d333032 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:DM5PR03MB2476; X-Microsoft-Exchange-Diagnostics: 1;DM5PR03MB2476;31:QvlbGLeSfDYpsGvRKdbGdtCO227DQTQuANS9GwEdRezVmvowOLHYPs1wDqto6qdWLtT+YRqioi5tObDwe21xs4WjDpCkcrYhi0eGdrijOVlCmMEF3pty4uroHi6Q8dcucP2TnLFXYY9bX5vPYMraVfrgHIudrTNsdWVJNd9FwDW7c+c6tV9+QlxmNSIPF5zqFT6nEmf7dKcYdQ5cteuPykIdt9zFgpN6yPOTJv9XFr2rgrJc/1NkDWtzf/SUfAyqa75fBruZIVJnmNHcWPN75g==;4:8eXMi0Qb4Yzg36xMUyp55CNHaPdHykzfLFkoIYxs/olQXuk3NtyzWJpXzqZvAPsmYXKqV0HsmlfX8+HRR9b1i/M59G9sOTD2QnDxB9V52JQ4MaCXjfDJqatpPSWEffHTpUxji054TJ48xHEouAvYGtzlCMPgFt+/o4o4ZUqFo0Vy0zETeB3uPgOMlgoQhrdokem+FjYOaGcA59aB0+eQ86amSu0eOaXcBAaa8yD/s4qq6g2F5sYd33fI3c6plUwJWKrbQA0cLSCV3AqkjZF7klrotIgsED3ulWow95YKqsfTlI4BFVhoKoDH0dWWY4KgB3ZkC55xJIT1sXu2d5t2zPQw1JW71CzY7pwAMV3/r0V/1ggGiekTfjghh8sHM7JkEwuxkHMCHKXdN4Z63MaSRM+GoE4ptL207bJyR5HuCqxR3OxN6kg78PD5RAzR3PpvGokKuyi0C61GvW09GTttSUZBNKtzYHy9wE5rmdEmUL4j6MFhZGW1oPuoEpxufevvgPPUH3pbTGoXv4S2wz7bZSfwIPXEP+qwiwov5Z7ezeIXXr8ZV5tgDQaCtNtqP0ReGyW7J+Kw/XvT+kzKZ8VHFFNW3ttH5iULZf9tloeboyM= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197)(275809806118684); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6095035)(601004)(2401047)(13023025)(8121501046)(13024025)(13017025)(13018025)(13015025)(5005006)(3002001)(10201501046)(6055026)(6096035);SRVR:DM5PR03MB2476;BCL:0;PCL:0;RULEID:(400006);SRVR:DM5PR03MB2476; X-Forefront-PRVS: 012792EC17 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DM5PR03MB2476;23:0VdVCm8DN73kpEqrnqT9l4eb+/s8WIbQGhtFeW2EE?= =?us-ascii?Q?BdS3lrs3irtTGOsO6s4KJK4wwLCjncirlltOWSWlpNSVqzSjEbvTs9y9BIQh?= =?us-ascii?Q?SJHoVX+1YKbVQKhRaD4p47ykcIivmnfcRubfmIfwI1SaV5xRQs0Fmov/8BSC?= =?us-ascii?Q?dZE4ghNUiCfZqcKAu372LVW83IQN/HXi4RUR6ryWlKXHaODd+i5lXHVEyUEl?= =?us-ascii?Q?cXvnddAqW6iAgTihYXUibCmAicwjyrer8fEeB1DQf7r7PqK5b7p8HCr3w5fd?= =?us-ascii?Q?2nTcQ7gjqgRh4sVVu9s3oTRL/V9LfYXayrZwO6tUkqAu9guqcC1AyLlPJVB5?= =?us-ascii?Q?Wm4mllZnpynAD0Z7xWU0qasFONLpNjmWTSmbwfOt1TpIxkHW+pIkvBBwD23i?= =?us-ascii?Q?JcHjev02Db+CyOO/32HlfFPHUH2WhDvStpxKq5+ryVBfsApP3OVIgkBjxXSu?= =?us-ascii?Q?68dH3UoFUVmmqFUC1rdEXyPBMT3q3aqtDPmy4sqm6XKtQ7K73OHhmwjeJadd?= =?us-ascii?Q?M1vjJVP+EfBV50zwhxSxBshBswIXEmPzDLze24Y8elCXGWMLDN79gmaac/BC?= =?us-ascii?Q?kXVdyFuN6UAbOZ0iS0deB4vrTwSM+bL60NPwpeopmat4avxadIjYkclXM6vH?= =?us-ascii?Q?U1Z6l/APpe6JZTI0wL/Kzejw0gLiccPG/hf+w8WASdwSS7BTZovjkJp0OMXj?= =?us-ascii?Q?1LiPq6LdnAi3g+0N0l4LISMab5d3qWmkx5kf7WB1+PAuoGVuRz08no2feUAs?= =?us-ascii?Q?KLA0haENTjWlyileipbc3WyzwwzpA0cb/P8Gsd8iVHwkB7USY8OL4e+iiqdY?= =?us-ascii?Q?mTzcJx87eaKq9jKALZhtvH791SE9A4Z6hPoMvl4w0V4XE3cOpi0AERPTtb3r?= =?us-ascii?Q?IQflTX4SzRJzsyMS3IfAvejdVS1KpBFP9P/w4nmBL20kvFS57y9quspDgPNz?= =?us-ascii?Q?+pQQw+sUZvPuM7O1IktzFoj0ZZQFoUhysq1vHL/AX+4+9b13NWVeNVBRFhQ1?= =?us-ascii?Q?nL9NJfV2drFPWZvQl425AbEX77QS7A0ki6o5PfPWX2AEKWbTC3jTMmLWoeLK?= =?us-ascii?Q?ShGWNe3n3kwwO6cCyKJ9xRTYu5kLV4cOS5olBQVUgI0GYDsbKkJ77Ha/EMJj?= =?us-ascii?Q?EPJZlnMinVGIKjFAVOoXJHyp4V0Gimj?= X-Microsoft-Exchange-Diagnostics: 1;DM5PR03MB2476;6:yNH3Pmw3kx6oNg+tk+JRpQuY+t0T16PhQ572TypmrOzvzNC+oh7sFHndMXwcpKMxdvTnKuVQKX5dpVjL0CYhGnFVpnpy6XcM+WF62JAoc95jq11BRdzQUO5ZVWRDOEtPkzNSyE/FbAAI3BBFnpbzFfXBUcVb/xlPD9A2eaPK289dmhMfeClaDX9TKU/XuL/pS13h1WXVQ0R8LPHhlDmUl72Dly0DrftGjwTK8Yb29lzrSP9ozxYY8lJ9xkZpkTiKDZhvScXpyYEk7EKVs5aWfyB2GYbXF5U7PPEZOaNahs25/b+8US9uZqDrB7T3GdtOoto+0326A9qNTSbBqP0zWw==;5:vcRdOfBZ3jVYUKwDgGAW/S+NgjATuRxgyXv0yq41Ujy9bRqqkm78IZypNqnKyJYwoxFbvRg7Bt6SN73bbcnq17xADRWA/ITN0YxFnn5dCxjdsSGeRkxTW7fCUUUNdD6+oxWywnYc2JovOW1prz87COtKCwa2x6Kfbm/HMcyjQMMzVxInf7tFjVydpnyNbRiE;24:XIc2U+nDQ+YxnqqEArOK9PxMnZTnSq+NLf5sASg8R9zCe6gRXfKIDIyacSx5HCuL1TLTD1N/tq5a68CZ4w6/PCsLn5cnvf/kRP2crDBed88= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;DM5PR03MB2476;7:8FVgGB5QaMnsbU1qbiU7h37JIPZn73HZUfwrDV6Z1M7p8B6/X04TANsF+TlNFsW96Kgi4e9z0SbDPCFbPgJD642/E7vUG1aocKWs0NPwcEsN0Phx/Del8ZQ/cGsoh+ydwD2bWOOhJU5nKD/hQX7XBQWPa1ioJ+YQ+jPQ89sLSGzHpTeNbae7pCl3UmfA/eRYTYmZRTpjOnPU477kzJJ7YGSRGVDm3uDa06GsonFM45/Ua0btSBrHbmgJFxZpCDgmCOjeWDsWci4MnZiM5U8iNqoJFlOh3RqbiaVopXgqKRNbsKaCam0anxilmqlVWnvXFG/Oatzy3OxT25uBsq631m4LRcvSWFpQLtv4vcKKi5g= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Nov 2016 08:41:26.6865 (UTC) X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e;Ip=[192.88.158.2];Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR03MB2476 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 | 54 +++++- drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 33 ++++ drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 199 +++++++++++++++++++++ 3 files changed, 284 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 0e7f1c7..fcb9cac 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -700,10 +700,15 @@ static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr, struct dpaa_priv *priv = (struct dpaa_priv *)container_of(cgr, struct dpaa_priv, 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); + } } static int dpaa_eth_cgr_init(struct dpaa_priv *priv) @@ -1217,6 +1222,37 @@ static void dpaa_fd_release(const struct net_device *net_dev, dpaa_bman_release(dpaa_bp, &bmb, 1); } +static void count_ern(struct dpaa_percpu_priv *percpu_priv, + const union 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. @@ -1882,6 +1918,7 @@ static int dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) likely(skb_shinfo(skb)->nr_frags < DPAA_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. @@ -1918,6 +1955,15 @@ static void dpaa_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++; + dpaa_fd_release(net_dev, fd); } @@ -1973,6 +2019,8 @@ static void dpaa_tx_conf(struct net_device *net_dev, percpu_priv->stats.tx_errors++; } + percpu_priv->tx_confirm++; + skb = dpaa_cleanup_tx_fd(priv, fd); consume_skb(skb); @@ -1987,6 +2035,7 @@ static inline int dpaa_eth_napi_schedule(struct dpaa_percpu_priv *percpu_priv, percpu_priv->np.p = portal; napi_schedule(&percpu_priv->np.napi); + percpu_priv->in_interrupt++; return 1; } return 0; @@ -2171,6 +2220,7 @@ static void egress_ern(struct qman_portal *portal, percpu_priv->stats.tx_dropped++; percpu_priv->stats.tx_fifo_errors++; + count_ern(percpu_priv, msg); skb = dpaa_cleanup_tx_fd(priv, fd); dev_kfree_skb_any(skb); diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index d6ab335..711fb06 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h @@ -95,6 +95,25 @@ struct dpaa_bp { atomic_t refs; }; +struct dpaa_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 dpaa_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 dpaa_napi_portal { struct napi_struct napi; struct qman_portal *p; @@ -104,7 +123,13 @@ struct dpaa_napi_portal { struct dpaa_percpu_priv { struct net_device *net_dev; struct dpaa_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 dpaa_rx_errors rx_errors; + struct dpaa_ern_cnt ern_cnt; }; struct dpaa_buffer_layout { @@ -133,6 +158,14 @@ struct dpaa_priv { * (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; diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c index 3580a62..27e7044 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c @@ -36,6 +36,42 @@ #include "dpaa_eth.h" #include "mac.h" +static const char dpaa_stats_percpu[][ETH_GSTRING_LEN] = { + "interrupts", + "rx packets", + "tx packets", + "tx confirm", + "tx S/G", + "tx error", + "rx error", +}; + +static char dpaa_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 DPAA_STATS_PERCPU_LEN ARRAY_SIZE(dpaa_stats_percpu) +#define DPAA_STATS_GLOBAL_LEN ARRAY_SIZE(dpaa_stats_global) + static int dpaa_get_settings(struct net_device *net_dev, struct ethtool_cmd *et_cmd) { @@ -205,6 +241,166 @@ static int dpaa_set_pauseparam(struct net_device *net_dev, return err; } +static int dpaa_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 * (DPAA_STATS_PERCPU_LEN + DPAA_BPS_NUM) + + DPAA_STATS_GLOBAL_LEN; + + switch (type) { + case ETH_SS_STATS: + return total_stats; + default: + return -EOPNOTSUPP; + } +} + +static void copy_stats(struct dpaa_percpu_priv *percpu_priv, int num_cpus, + int crr_cpu, u64 *bp_count, u64 *data) +{ + int num_values = num_cpus + 1; + int crr = 0, j; + + /* 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; + + for (j = 0; j < DPAA_BPS_NUM; j++) { + data[crr * num_values + crr_cpu] = bp_count[j]; + data[crr++ * num_values + num_cpus] += bp_count[j]; + } +} + +static void dpaa_get_ethtool_stats(struct net_device *net_dev, + struct ethtool_stats *stats, u64 *data) +{ + u64 bp_count[DPAA_BPS_NUM], cg_time, cg_num; + struct dpaa_percpu_priv *percpu_priv; + struct dpaa_rx_errors rx_errors; + unsigned int num_cpus, offset; + struct dpaa_ern_cnt ern_cnt; + struct dpaa_bp *dpaa_bp; + struct dpaa_priv *priv; + int total_stats, i, j; + bool cg_status; + + total_stats = dpaa_get_sset_count(net_dev, ETH_SS_STATS); + priv = netdev_priv(net_dev); + num_cpus = num_online_cpus(); + + memset(&bp_count, 0, sizeof(bp_count)); + memset(&rx_errors, 0, sizeof(struct dpaa_rx_errors)); + memset(&ern_cnt, 0, sizeof(struct dpaa_ern_cnt)); + memset(data, 0, total_stats * sizeof(u64)); + + for_each_online_cpu(i) { + percpu_priv = per_cpu_ptr(priv->percpu_priv, i); + for (j = 0; j < DPAA_BPS_NUM; j++) { + dpaa_bp = priv->dpaa_bps[j]; + if (!dpaa_bp->percpu_count) + continue; + bp_count[j] = *(per_cpu_ptr(dpaa_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) * (DPAA_STATS_PERCPU_LEN + DPAA_BPS_NUM); + memcpy(data + offset, &rx_errors, sizeof(struct dpaa_rx_errors)); + + offset += sizeof(struct dpaa_rx_errors) / sizeof(u64); + memcpy(data + offset, &ern_cnt, sizeof(struct dpaa_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_congested(&priv->cgr_data.cgr, &cg_status) == 0) { + cg_num = priv->cgr_data.cgr_congested_count; + + /* reset congestion stats (like QMan API does */ + priv->cgr_data.congested_jiffies = 0; + priv->cgr_data.cgr_congested_count = 0; + } + + offset += sizeof(struct dpaa_ern_cnt) / sizeof(u64); + data[offset++] = cg_time; + data[offset++] = cg_num; + data[offset++] = cg_status; +} + +static void dpaa_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; + + memset(string_cpu, 0, sizeof(string_cpu)); + strings = data; + num_cpus = num_online_cpus(); + size = DPAA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN; + + for (i = 0; i < DPAA_STATS_PERCPU_LEN; i++) { + for (j = 0; j < num_cpus; j++) { + snprintf(string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", + dpaa_stats_percpu[i], j); + memcpy(strings, string_cpu, ETH_GSTRING_LEN); + strings += ETH_GSTRING_LEN; + } + snprintf(string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", + dpaa_stats_percpu[i]); + memcpy(strings, string_cpu, ETH_GSTRING_LEN); + strings += ETH_GSTRING_LEN; + } + for (i = 0; i < DPAA_BPS_NUM; i++) { + for (j = 0; j < num_cpus; j++) { + snprintf(string_cpu, ETH_GSTRING_LEN, + "bpool %c [CPU %d]", 'a' + i, j); + memcpy(strings, string_cpu, ETH_GSTRING_LEN); + strings += ETH_GSTRING_LEN; + } + snprintf(string_cpu, ETH_GSTRING_LEN, "bpool %c [TOTAL]", + 'a' + i); + memcpy(strings, string_cpu, ETH_GSTRING_LEN); + strings += ETH_GSTRING_LEN; + } + memcpy(strings, dpaa_stats_global, size); +} + const struct ethtool_ops dpaa_ethtool_ops = { .get_settings = dpaa_get_settings, .set_settings = dpaa_set_settings, @@ -215,4 +411,7 @@ const struct ethtool_ops dpaa_ethtool_ops = { .get_pauseparam = dpaa_get_pauseparam, .set_pauseparam = dpaa_set_pauseparam, .get_link = ethtool_op_get_link, + .get_sset_count = dpaa_get_sset_count, + .get_ethtool_stats = dpaa_get_ethtool_stats, + .get_strings = dpaa_get_strings, }; -- 2.1.0