Commit 472e12e7 authored by David S. Miller's avatar David S. Miller

Merge branch 'dpaa2-eth-Add-new-statistics-counters'

Ioana Radulescu says:

====================
dpaa2-eth: Add new statistics counters

Recent firmware versions offer access to more DPNI statistics
counters. Add the relevant ones to ethtool interface stats.

Also we can now make use of a new counter for in flight egress frames
to avoid sleeping an arbitrary amount of time in the ndo_stop routine.

v2: in patch 2/3, treat separately the error case for unsupported
statistics pages
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2c1f9e26 52b6a4ff
...@@ -1348,7 +1348,7 @@ static u32 ingress_fq_count(struct dpaa2_eth_priv *priv) ...@@ -1348,7 +1348,7 @@ static u32 ingress_fq_count(struct dpaa2_eth_priv *priv)
return total; return total;
} }
static void wait_for_fq_empty(struct dpaa2_eth_priv *priv) static void wait_for_ingress_fq_empty(struct dpaa2_eth_priv *priv)
{ {
int retries = 10; int retries = 10;
u32 pending; u32 pending;
...@@ -1360,6 +1360,31 @@ static void wait_for_fq_empty(struct dpaa2_eth_priv *priv) ...@@ -1360,6 +1360,31 @@ static void wait_for_fq_empty(struct dpaa2_eth_priv *priv)
} while (pending && --retries); } while (pending && --retries);
} }
#define DPNI_TX_PENDING_VER_MAJOR 7
#define DPNI_TX_PENDING_VER_MINOR 13
static void wait_for_egress_fq_empty(struct dpaa2_eth_priv *priv)
{
union dpni_statistics stats;
int retries = 10;
int err;
if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_TX_PENDING_VER_MAJOR,
DPNI_TX_PENDING_VER_MINOR) < 0)
goto out;
do {
err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token, 6,
&stats);
if (err)
goto out;
if (stats.page_6.tx_pending_frames == 0)
return;
} while (--retries);
out:
msleep(500);
}
static int dpaa2_eth_stop(struct net_device *net_dev) static int dpaa2_eth_stop(struct net_device *net_dev)
{ {
struct dpaa2_eth_priv *priv = netdev_priv(net_dev); struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
...@@ -1379,7 +1404,7 @@ static int dpaa2_eth_stop(struct net_device *net_dev) ...@@ -1379,7 +1404,7 @@ static int dpaa2_eth_stop(struct net_device *net_dev)
* on WRIOP. After it finishes, wait until all remaining frames on Rx * on WRIOP. After it finishes, wait until all remaining frames on Rx
* and Tx conf queues are consumed on NAPI poll. * and Tx conf queues are consumed on NAPI poll.
*/ */
msleep(500); wait_for_egress_fq_empty(priv);
do { do {
dpni_disable(priv->mc_io, 0, priv->mc_token); dpni_disable(priv->mc_io, 0, priv->mc_token);
...@@ -1395,7 +1420,7 @@ static int dpaa2_eth_stop(struct net_device *net_dev) ...@@ -1395,7 +1420,7 @@ static int dpaa2_eth_stop(struct net_device *net_dev)
*/ */
} }
wait_for_fq_empty(priv); wait_for_ingress_fq_empty(priv);
disable_ch_napi(priv); disable_ch_napi(priv);
/* Empty the buffer pool */ /* Empty the buffer pool */
......
...@@ -28,6 +28,11 @@ static char dpaa2_ethtool_stats[][ETH_GSTRING_LEN] = { ...@@ -28,6 +28,11 @@ static char dpaa2_ethtool_stats[][ETH_GSTRING_LEN] = {
"[hw] rx nobuffer discards", "[hw] rx nobuffer discards",
"[hw] tx discarded frames", "[hw] tx discarded frames",
"[hw] tx confirmed frames", "[hw] tx confirmed frames",
"[hw] tx dequeued bytes",
"[hw] tx dequeued frames",
"[hw] tx rejected bytes",
"[hw] tx rejected frames",
"[hw] tx pending frames",
}; };
#define DPAA2_ETH_NUM_STATS ARRAY_SIZE(dpaa2_ethtool_stats) #define DPAA2_ETH_NUM_STATS ARRAY_SIZE(dpaa2_ethtool_stats)
...@@ -188,27 +193,33 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev, ...@@ -188,27 +193,33 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
struct dpaa2_eth_priv *priv = netdev_priv(net_dev); struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
struct dpaa2_eth_drv_stats *extras; struct dpaa2_eth_drv_stats *extras;
struct dpaa2_eth_ch_stats *ch_stats; struct dpaa2_eth_ch_stats *ch_stats;
int dpni_stats_page_size[DPNI_STATISTICS_CNT] = {
sizeof(dpni_stats.page_0),
sizeof(dpni_stats.page_1),
sizeof(dpni_stats.page_2),
sizeof(dpni_stats.page_3),
sizeof(dpni_stats.page_4),
sizeof(dpni_stats.page_5),
sizeof(dpni_stats.page_6),
};
memset(data, 0, memset(data, 0,
sizeof(u64) * (DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS)); sizeof(u64) * (DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS));
/* Print standard counters, from DPNI statistics */ /* Print standard counters, from DPNI statistics */
for (j = 0; j <= 2; j++) { for (j = 0; j <= 6; j++) {
/* We're not interested in pages 4 & 5 for now */
if (j == 4 || j == 5)
continue;
err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token, err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token,
j, &dpni_stats); j, &dpni_stats);
if (err != 0) if (err == -EINVAL)
/* Older firmware versions don't support all pages */
memset(&dpni_stats, 0, sizeof(dpni_stats));
else
netdev_warn(net_dev, "dpni_get_stats(%d) failed\n", j); netdev_warn(net_dev, "dpni_get_stats(%d) failed\n", j);
switch (j) {
case 0: num_cnt = dpni_stats_page_size[j] / sizeof(u64);
num_cnt = sizeof(dpni_stats.page_0) / sizeof(u64);
break;
case 1:
num_cnt = sizeof(dpni_stats.page_1) / sizeof(u64);
break;
case 2:
num_cnt = sizeof(dpni_stats.page_2) / sizeof(u64);
break;
}
for (k = 0; k < num_cnt; k++) for (k = 0; k < num_cnt; k++)
*(data + i++) = dpni_stats.raw.counter[k]; *(data + i++) = dpni_stats.raw.counter[k];
} }
......
...@@ -1470,7 +1470,7 @@ int dpni_get_queue(struct fsl_mc_io *mc_io, ...@@ -1470,7 +1470,7 @@ int dpni_get_queue(struct fsl_mc_io *mc_io,
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPNI object * @token: Token of DPNI object
* @page: Selects the statistics page to retrieve, see * @page: Selects the statistics page to retrieve, see
* DPNI_GET_STATISTICS output. Pages are numbered 0 to 2. * DPNI_GET_STATISTICS output. Pages are numbered 0 to 6.
* @stat: Structure containing the statistics * @stat: Structure containing the statistics
* *
* Return: '0' on Success; Error code otherwise. * Return: '0' on Success; Error code otherwise.
......
...@@ -416,6 +416,26 @@ int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io, ...@@ -416,6 +416,26 @@ int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
* lack of buffers * lack of buffers
* @page_2.egress_discarded_frames: Egress discarded frame count * @page_2.egress_discarded_frames: Egress discarded frame count
* @page_2.egress_confirmed_frames: Egress confirmed frame count * @page_2.egress_confirmed_frames: Egress confirmed frame count
* @page3: Page_3 statistics structure
* @page_3.egress_dequeue_bytes: Cumulative count of the number of bytes
* dequeued from egress FQs
* @page_3.egress_dequeue_frames: Cumulative count of the number of frames
* dequeued from egress FQs
* @page_3.egress_reject_bytes: Cumulative count of the number of bytes in
* egress frames whose enqueue was rejected
* @page_3.egress_reject_frames: Cumulative count of the number of egress
* frames whose enqueue was rejected
* @page_4: Page_4 statistics structure: congestion points
* @page_4.cgr_reject_frames: number of rejected frames due to congestion point
* @page_4.cgr_reject_bytes: number of rejected bytes due to congestion point
* @page_5: Page_5 statistics structure: policer
* @page_5.policer_cnt_red: NUmber of red colored frames
* @page_5.policer_cnt_yellow: number of yellow colored frames
* @page_5.policer_cnt_green: number of green colored frames
* @page_5.policer_cnt_re_red: number of recolored red frames
* @page_5.policer_cnt_re_yellow: number of recolored yellow frames
* @page_6: Page_6 statistics structure
* @page_6.tx_pending_frames: total number of frames pending in egress FQs
* @raw: raw statistics structure, used to index counters * @raw: raw statistics structure, used to index counters
*/ */
union dpni_statistics { union dpni_statistics {
...@@ -442,6 +462,26 @@ union dpni_statistics { ...@@ -442,6 +462,26 @@ union dpni_statistics {
u64 egress_discarded_frames; u64 egress_discarded_frames;
u64 egress_confirmed_frames; u64 egress_confirmed_frames;
} page_2; } page_2;
struct {
u64 egress_dequeue_bytes;
u64 egress_dequeue_frames;
u64 egress_reject_bytes;
u64 egress_reject_frames;
} page_3;
struct {
u64 cgr_reject_frames;
u64 cgr_reject_bytes;
} page_4;
struct {
u64 policer_cnt_red;
u64 policer_cnt_yellow;
u64 policer_cnt_green;
u64 policer_cnt_re_red;
u64 policer_cnt_re_yellow;
} page_5;
struct {
u64 tx_pending_frames;
} page_6;
struct { struct {
u64 counter[DPNI_STATISTICS_CNT]; u64 counter[DPNI_STATISTICS_CNT];
} raw; } raw;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment