[PATCH 0/6] Add the 'net stats' command to dump network statistics

This patch set extends the 'net' command so that it can be used to dump network statistics on the available devices. The first user of this new API is the ldpaa_eth driver which, in the last patch, implements the 3 new callbacks added.
Since the ldpaa_eth driver already had some debug printing of counters, the first 4 patches are there to extend the existing list of counters and to reorganize the code so that it fits better with the new eth_ops callbacks.
Ioana Ciornei (6): net: ldpaa_eth: fix the memory layout of the dpmac_get_counters() API net: ldpaa_eth: transform dpni_statistics from a struct to a union net: ldpaa_eth: extend debug capabilities with DPNI statistics net: ldpaa_eth: extend debug capabilities with DPMAC statistics cmd: net: add a 'net stats' command to dump network statistics net: ldpaa_eth: export DPNI and DPMAC counters through 'net stats'
cmd/net.c | 54 ++++++- drivers/net/fsl-mc/dpni.c | 2 +- drivers/net/ldpaa_eth/ldpaa_eth.c | 248 +++++++++++++++--------------- drivers/net/ldpaa_eth/ldpaa_eth.h | 64 ++++++++ include/fsl-mc/fsl_dpmac.h | 7 +- include/fsl-mc/fsl_dpni.h | 143 ++++++++++++----- include/net.h | 6 + 7 files changed, 353 insertions(+), 171 deletions(-)

Each MC commands has a specific predefined memory layout that gets interpreted by the firmware. The dpmac_get_counters() API memory layout is wrong, thus the results returned by the command are incorrect.
Fix this by updating the offset of the counter field.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com --- include/fsl-mc/fsl_dpmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/fsl-mc/fsl_dpmac.h b/include/fsl-mc/fsl_dpmac.h index 1cea123a3164..8f5e17fe222a 100644 --- a/include/fsl-mc/fsl_dpmac.h +++ b/include/fsl-mc/fsl_dpmac.h @@ -84,7 +84,7 @@ do { \
/* cmd, param, offset, width, type, arg_name */ #define DPMAC_CMD_GET_COUNTER(cmd, type) \ - MC_CMD_OP(cmd, 1, 0, 64, enum dpmac_counter, type) + MC_CMD_OP(cmd, 0, 0, 8, enum dpmac_counter, type)
/* cmd, param, offset, width, type, arg_name */ #define DPMAC_RSP_GET_COUNTER(cmd, counter) \

On Tue, May 23, 2023 at 4:48 PM Ioana Ciornei ioana.ciornei@nxp.com wrote:
Each MC commands has a specific predefined memory layout that gets interpreted by the firmware. The dpmac_get_counters() API memory layout is wrong, thus the results returned by the command are incorrect.
Fix this by updating the offset of the counter field.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com
include/fsl-mc/fsl_dpmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/fsl-mc/fsl_dpmac.h b/include/fsl-mc/fsl_dpmac.h index 1cea123a3164..8f5e17fe222a 100644 --- a/include/fsl-mc/fsl_dpmac.h +++ b/include/fsl-mc/fsl_dpmac.h @@ -84,7 +84,7 @@ do { \
/* cmd, param, offset, width, type, arg_name */ #define DPMAC_CMD_GET_COUNTER(cmd, type) \
MC_CMD_OP(cmd, 1, 0, 64, enum dpmac_counter, type)
MC_CMD_OP(cmd, 0, 0, 8, enum dpmac_counter, type)
/* cmd, param, offset, width, type, arg_name */
#define DPMAC_RSP_GET_COUNTER(cmd, counter) \
2.25.1
Reviewed-by: Ramon Fried rfried.dev@gmail.com

In order to simplify code, dpni_statistics can be written as a union. Using the raw accessors we can just loop through all the statistics from a page without trying to access each an every one independently. Make this change to a union.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com --- drivers/net/fsl-mc/dpni.c | 2 +- drivers/net/ldpaa_eth/ldpaa_eth.c | 4 +- include/fsl-mc/fsl_dpni.h | 143 +++++++++++++++++++++--------- 3 files changed, 105 insertions(+), 44 deletions(-)
diff --git a/drivers/net/fsl-mc/dpni.c b/drivers/net/fsl-mc/dpni.c index 5290be20c85e..a31abbff71b9 100644 --- a/drivers/net/fsl-mc/dpni.c +++ b/drivers/net/fsl-mc/dpni.c @@ -491,7 +491,7 @@ int dpni_get_statistics(struct fsl_mc_io *mc_io, uint32_t cmd_flags, uint16_t token, uint8_t page, - struct dpni_statistics *stat) + union dpni_statistics *stat) { struct mc_command cmd = { 0 }; int err; diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 2cb6e9b7d705..fe901baf5a4e 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -68,7 +68,7 @@ static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = { };
static void print_dpni_stats(const char *strings[], - struct dpni_statistics dpni_stats) + union dpni_statistics dpni_stats) { uint64_t *stat; int i; @@ -86,7 +86,7 @@ static void ldpaa_eth_get_dpni_counter(void) { int err = 0; unsigned int page = 0; - struct dpni_statistics dpni_stats; + union dpni_statistics dpni_stats;
printf("DPNI counters ..\n"); for (page = 0; page < 3; page++) { diff --git a/include/fsl-mc/fsl_dpni.h b/include/fsl-mc/fsl_dpni.h index e5e7338192f6..fc57c375ac14 100644 --- a/include/fsl-mc/fsl_dpni.h +++ b/include/fsl-mc/fsl_dpni.h @@ -258,13 +258,13 @@ do { \ /* cmd, param, offset, width, type, arg_name */ #define DPNI_RSP_GET_STATISTICS(cmd, stat) \ do { \ - MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->counter0); \ - MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->counter1); \ - MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->counter2); \ - MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->counter3); \ - MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->counter4); \ - MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->counter5); \ - MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->counter6); \ + MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \ + MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \ + MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \ + MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \ + MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \ + MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \ } while (0)
enum net_prot { @@ -1257,40 +1257,101 @@ int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io, uint32_t cmd_flags, uint16_t token, enum dpni_confirmation_mode mode); -struct dpni_statistics { - /** - * Page_0 statistics structure - * @ingress_all_frames: Ingress frame count - * @ingress_all_bytes: Ingress byte count - * @ingress_multicast_frames: Ingress multicast frame count - * @ingress_multicast_bytes: Ingress multicast byte count - * @ingress_broadcast_frames: Ingress broadcast frame count - * @ingress_broadcast_bytes: Ingress broadcast byte count - * - * Page_1 statistics structure - * @egress_all_frames: Egress frame count - * @egress_all_bytes: Egress byte count - * @egress_multicast_frames: Egress multicast frame count - * @egress_multicast_bytes: Egress multicast byte count - * @egress_broadcast_frames: Egress broadcast frame count - * @egress_broadcast_bytes: Egress broadcast byte count - * - * Page_2 statistics structure - * @ingress_filtered_frames: Ingress filtered frame count - * @ingress_discarded_frames: Ingress discarded frame count - * @ingress_nobuffer_discards: Ingress discarded frame count due to - * lack of buffers. - * @egress_discarded_frames: Egress discarded frame count - * @egress_confirmed_frames: Egress confirmed frame count - */
- uint64_t counter0; - uint64_t counter1; - uint64_t counter2; - uint64_t counter3; - uint64_t counter4; - uint64_t counter5; - uint64_t counter6; +#define DPNI_STATISTICS_CNT 7 + +/** + * union dpni_statistics - Union describing the DPNI statistics + * @page_0: Page_0 statistics structure + * @page_0.ingress_all_frames: Ingress frame count + * @page_0.ingress_all_bytes: Ingress byte count + * @page_0.ingress_multicast_frames: Ingress multicast frame count + * @page_0.ingress_multicast_bytes: Ingress multicast byte count + * @page_0.ingress_broadcast_frames: Ingress broadcast frame count + * @page_0.ingress_broadcast_bytes: Ingress broadcast byte count + * @page_1: Page_1 statistics structure + * @page_1.egress_all_frames: Egress frame count + * @page_1.egress_all_bytes: Egress byte count + * @page_1.egress_multicast_frames: Egress multicast frame count + * @page_1.egress_multicast_bytes: Egress multicast byte count + * @page_1.egress_broadcast_frames: Egress broadcast frame count + * @page_1.egress_broadcast_bytes: Egress broadcast byte count + * @page_2: Page_2 statistics structure + * @page_2.ingress_filtered_frames: Ingress filtered frame count + * @page_2.ingress_discarded_frames: Ingress discarded frame count + * @page_2.ingress_nobuffer_discards: Ingress discarded frame count due to + * lack of buffers + * @page_2.egress_discarded_frames: Egress discarded frame count + * @page_2.egress_confirmed_frames: Egress confirmed frame count + * @page_3: 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 + */ +union dpni_statistics { + struct { + u64 ingress_all_frames; + u64 ingress_all_bytes; + u64 ingress_multicast_frames; + u64 ingress_multicast_bytes; + u64 ingress_broadcast_frames; + u64 ingress_broadcast_bytes; + } page_0; + struct { + u64 egress_all_frames; + u64 egress_all_bytes; + u64 egress_multicast_frames; + u64 egress_multicast_bytes; + u64 egress_broadcast_frames; + u64 egress_broadcast_bytes; + } page_1; + struct { + u64 ingress_filtered_frames; + u64 ingress_discarded_frames; + u64 ingress_nobuffer_discards; + u64 egress_discarded_frames; + u64 egress_confirmed_frames; + } 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 { + u64 counter[DPNI_STATISTICS_CNT]; + } raw; };
/** @@ -1308,7 +1369,7 @@ int dpni_get_statistics(struct fsl_mc_io *mc_io, uint32_t cmd_flags, uint16_t token, uint8_t page, - struct dpni_statistics *stat); + union dpni_statistics *stat);
/** * dpni_reset_statistics() - Clears DPNI statistics

On Tue, May 23, 2023 at 4:48 PM Ioana Ciornei ioana.ciornei@nxp.com wrote:
In order to simplify code, dpni_statistics can be written as a union. Using the raw accessors we can just loop through all the statistics from a page without trying to access each an every one independently. Make this change to a union.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com
drivers/net/fsl-mc/dpni.c | 2 +- drivers/net/ldpaa_eth/ldpaa_eth.c | 4 +- include/fsl-mc/fsl_dpni.h | 143 +++++++++++++++++++++--------- 3 files changed, 105 insertions(+), 44 deletions(-)
diff --git a/drivers/net/fsl-mc/dpni.c b/drivers/net/fsl-mc/dpni.c index 5290be20c85e..a31abbff71b9 100644 --- a/drivers/net/fsl-mc/dpni.c +++ b/drivers/net/fsl-mc/dpni.c @@ -491,7 +491,7 @@ int dpni_get_statistics(struct fsl_mc_io *mc_io, uint32_t cmd_flags, uint16_t token, uint8_t page,
struct dpni_statistics *stat)
union dpni_statistics *stat)
{ struct mc_command cmd = { 0 }; int err; diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 2cb6e9b7d705..fe901baf5a4e 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -68,7 +68,7 @@ static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = { };
static void print_dpni_stats(const char *strings[],
struct dpni_statistics dpni_stats)
union dpni_statistics dpni_stats)
{ uint64_t *stat; int i; @@ -86,7 +86,7 @@ static void ldpaa_eth_get_dpni_counter(void) { int err = 0; unsigned int page = 0;
struct dpni_statistics dpni_stats;
union dpni_statistics dpni_stats; printf("DPNI counters ..\n"); for (page = 0; page < 3; page++) {
diff --git a/include/fsl-mc/fsl_dpni.h b/include/fsl-mc/fsl_dpni.h index e5e7338192f6..fc57c375ac14 100644 --- a/include/fsl-mc/fsl_dpni.h +++ b/include/fsl-mc/fsl_dpni.h @@ -258,13 +258,13 @@ do { \ /* cmd, param, offset, width, type, arg_name */ #define DPNI_RSP_GET_STATISTICS(cmd, stat) \ do { \
MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->counter0); \
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->counter1); \
MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->counter2); \
MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->counter3); \
MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->counter4); \
MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->counter5); \
MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->counter6); \
MC_RSP_OP(cmd, 0, 0, 64, uint64_t, (stat)->raw.counter[0]); \
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, (stat)->raw.counter[1]); \
MC_RSP_OP(cmd, 2, 0, 64, uint64_t, (stat)->raw.counter[2]); \
MC_RSP_OP(cmd, 3, 0, 64, uint64_t, (stat)->raw.counter[3]); \
MC_RSP_OP(cmd, 4, 0, 64, uint64_t, (stat)->raw.counter[4]); \
MC_RSP_OP(cmd, 5, 0, 64, uint64_t, (stat)->raw.counter[5]); \
MC_RSP_OP(cmd, 6, 0, 64, uint64_t, (stat)->raw.counter[6]); \
} while (0)
enum net_prot { @@ -1257,40 +1257,101 @@ int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io, uint32_t cmd_flags, uint16_t token, enum dpni_confirmation_mode mode); -struct dpni_statistics {
/**
* Page_0 statistics structure
* @ingress_all_frames: Ingress frame count
* @ingress_all_bytes: Ingress byte count
* @ingress_multicast_frames: Ingress multicast frame count
* @ingress_multicast_bytes: Ingress multicast byte count
* @ingress_broadcast_frames: Ingress broadcast frame count
* @ingress_broadcast_bytes: Ingress broadcast byte count
*
* Page_1 statistics structure
* @egress_all_frames: Egress frame count
* @egress_all_bytes: Egress byte count
* @egress_multicast_frames: Egress multicast frame count
* @egress_multicast_bytes: Egress multicast byte count
* @egress_broadcast_frames: Egress broadcast frame count
* @egress_broadcast_bytes: Egress broadcast byte count
*
* Page_2 statistics structure
* @ingress_filtered_frames: Ingress filtered frame count
* @ingress_discarded_frames: Ingress discarded frame count
* @ingress_nobuffer_discards: Ingress discarded frame count due to
* lack of buffers.
* @egress_discarded_frames: Egress discarded frame count
* @egress_confirmed_frames: Egress confirmed frame count
*/
uint64_t counter0;
uint64_t counter1;
uint64_t counter2;
uint64_t counter3;
uint64_t counter4;
uint64_t counter5;
uint64_t counter6;
+#define DPNI_STATISTICS_CNT 7
+/**
- union dpni_statistics - Union describing the DPNI statistics
- @page_0: Page_0 statistics structure
- @page_0.ingress_all_frames: Ingress frame count
- @page_0.ingress_all_bytes: Ingress byte count
- @page_0.ingress_multicast_frames: Ingress multicast frame count
- @page_0.ingress_multicast_bytes: Ingress multicast byte count
- @page_0.ingress_broadcast_frames: Ingress broadcast frame count
- @page_0.ingress_broadcast_bytes: Ingress broadcast byte count
- @page_1: Page_1 statistics structure
- @page_1.egress_all_frames: Egress frame count
- @page_1.egress_all_bytes: Egress byte count
- @page_1.egress_multicast_frames: Egress multicast frame count
- @page_1.egress_multicast_bytes: Egress multicast byte count
- @page_1.egress_broadcast_frames: Egress broadcast frame count
- @page_1.egress_broadcast_bytes: Egress broadcast byte count
- @page_2: Page_2 statistics structure
- @page_2.ingress_filtered_frames: Ingress filtered frame count
- @page_2.ingress_discarded_frames: Ingress discarded frame count
- @page_2.ingress_nobuffer_discards: Ingress discarded frame count due to
lack of buffers
- @page_2.egress_discarded_frames: Egress discarded frame count
- @page_2.egress_confirmed_frames: Egress confirmed frame count
- @page_3: 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
- */
+union dpni_statistics {
struct {
u64 ingress_all_frames;
u64 ingress_all_bytes;
u64 ingress_multicast_frames;
u64 ingress_multicast_bytes;
u64 ingress_broadcast_frames;
u64 ingress_broadcast_bytes;
} page_0;
struct {
u64 egress_all_frames;
u64 egress_all_bytes;
u64 egress_multicast_frames;
u64 egress_multicast_bytes;
u64 egress_broadcast_frames;
u64 egress_broadcast_bytes;
} page_1;
struct {
u64 ingress_filtered_frames;
u64 ingress_discarded_frames;
u64 ingress_nobuffer_discards;
u64 egress_discarded_frames;
u64 egress_confirmed_frames;
} 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 {
u64 counter[DPNI_STATISTICS_CNT];
} raw;
};
/** @@ -1308,7 +1369,7 @@ int dpni_get_statistics(struct fsl_mc_io *mc_io, uint32_t cmd_flags, uint16_t token, uint8_t page,
struct dpni_statistics *stat);
union dpni_statistics *stat);
/**
- dpni_reset_statistics() - Clears DPNI statistics
-- 2.25.1
Reviewed-by: Ramon Fried rfried.dev@gmail.com

The ldpaa_eth driver already had a DPNI statistics dump, this patch extends the list of stats and adds a bit more structure to the code.
For a bit more context, the DPAA2 u-boot software architecture uses a default network interface object - a DPNI - which, at runtime, will get connected to the currently used DPMAC object. Each time the .stop() eth callback is called, the DPNI is reset to its original state, including its counters.
As a preparation for the next patches, we add a software kept set of DPNI counters which will get updated before each reset operation takes place.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com --- drivers/net/ldpaa_eth/ldpaa_eth.c | 106 +++++++++++++++--------------- drivers/net/ldpaa_eth/ldpaa_eth.h | 30 +++++++++ 2 files changed, 82 insertions(+), 54 deletions(-)
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index fe901baf5a4e..907e51da6e1e 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -38,68 +38,56 @@ static void init_phy(struct udevice *dev) } #endif
-#ifdef DEBUG +static void ldpaa_eth_collect_dpni_stats(struct udevice *dev, u64 *data) +{ + union dpni_statistics dpni_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), + }; + int j, k, num_cnt, err, i = 0;
-#define DPNI_STATS_PER_PAGE 6 - -static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = { - { - "DPNI_CNT_ING_ALL_FRAMES", - "DPNI_CNT_ING_ALL_BYTES", - "DPNI_CNT_ING_MCAST_FRAMES", - "DPNI_CNT_ING_MCAST_BYTES", - "DPNI_CNT_ING_BCAST_FRAMES", - "DPNI_CNT_ING_BCAST_BYTES", - }, { - "DPNI_CNT_EGR_ALL_FRAMES", - "DPNI_CNT_EGR_ALL_BYTES", - "DPNI_CNT_EGR_MCAST_FRAMES", - "DPNI_CNT_EGR_MCAST_BYTES", - "DPNI_CNT_EGR_BCAST_FRAMES", - "DPNI_CNT_EGR_BCAST_BYTES", - }, { - "DPNI_CNT_ING_FILTERED_FRAMES", - "DPNI_CNT_ING_DISCARDED_FRAMES", - "DPNI_CNT_ING_NOBUFFER_DISCARDS", - "DPNI_CNT_EGR_DISCARDED_FRAMES", - "DPNI_CNT_EGR_CNF_FRAMES", - "" - }, -}; + 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(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + j, &dpni_stats); + if (err) { + memset(&dpni_stats, 0, sizeof(dpni_stats)); + printf("dpni_get_stats(%d) failed\n", j); + } + + num_cnt = dpni_stats_page_size[j] / sizeof(u64); + for (k = 0; k < num_cnt; k++) + *(data + i++) = dpni_stats.raw.counter[k]; + } +}
-static void print_dpni_stats(const char *strings[], - union dpni_statistics dpni_stats) +static void ldpaa_eth_add_dpni_stats(struct udevice *dev, u64 *data) { - uint64_t *stat; + struct ldpaa_eth_priv *priv = dev_get_priv(dev); int i;
- stat = (uint64_t *)&dpni_stats; - for (i = 0; i < DPNI_STATS_PER_PAGE; i++) { - if (strcmp(strings[i], "\0") == 0) - break; - printf("%s= %llu\n", strings[i], *stat); - stat++; - } + for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++) + priv->dpni_stats[i] += data[i]; }
-static void ldpaa_eth_get_dpni_counter(void) +#ifdef DEBUG + +static void ldpaa_eth_dump_dpni_stats(struct udevice *dev, u64 *data) { - int err = 0; - unsigned int page = 0; - union dpni_statistics dpni_stats; + int i;
- printf("DPNI counters ..\n"); - for (page = 0; page < 3; page++) { - err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS, - dflt_dpni->dpni_handle, page, - &dpni_stats); - if (err < 0) { - printf("dpni_get_statistics: failed:"); - printf("%d for page[%d]\n", err, page); - return; - } - print_dpni_stats(dpni_statistics[page], dpni_stats); - } + printf("DPNI counters:\n"); + for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++) + printf(" %s: %llu\n", ldpaa_eth_dpni_stat_strings[i], data[i]); }
static void ldpaa_eth_get_dpmac_counter(struct udevice *dev) @@ -556,12 +544,22 @@ static void ldpaa_eth_stop(struct udevice *dev) struct ldpaa_eth_priv *priv = dev_get_priv(dev); struct phy_device *phydev = NULL; int err = 0; + u64 *data;
if (!eth_is_active(dev)) return;
+ data = kzalloc(sizeof(u64) * LDPAA_ETH_DPNI_NUM_STATS, GFP_KERNEL); + if (data) { + ldpaa_eth_collect_dpni_stats(dev, data); + ldpaa_eth_add_dpni_stats(dev, data); +#ifdef DEBUG + ldpaa_eth_dump_dpni_stats(dev, data); +#endif + } + kfree(data); + #ifdef DEBUG - ldpaa_eth_get_dpni_counter(); ldpaa_eth_get_dpmac_counter(dev); #endif
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h index 16d0106233e0..62dc9dd31029 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.h +++ b/drivers/net/ldpaa_eth/ldpaa_eth.h @@ -115,6 +115,33 @@ struct ldpaa_fas { LDPAA_ETH_FAS_MNLE | \ LDPAA_ETH_FAS_TIDE)
+static const char ldpaa_eth_dpni_stat_strings[][ETH_GSTRING_LEN] = { + "[dpni ] rx frames", + "[dpni ] rx bytes", + "[dpni ] rx mcast frames", + "[dpni ] rx mcast bytes", + "[dpni ] rx bcast frames", + "[dpni ] rx bcast bytes", + "[dpni ] tx frames", + "[dpni ] tx bytes", + "[dpni ] tx mcast frames", + "[dpni ] tx mcast bytes", + "[dpni ] tx bcast frames", + "[dpni ] tx bcast bytes", + "[dpni ] rx filtered frames", + "[dpni ] rx discarded frames", + "[dpni ] rx nobuffer discards", + "[dpni ] tx discarded frames", + "[dpni ] tx confirmed frames", + "[dpni ] tx dequeued bytes", + "[dpni ] tx dequeued frames", + "[dpni ] tx rejected bytes", + "[dpni ] tx rejected frames", + "[dpni ] tx pending frames", +}; + +#define LDPAA_ETH_DPNI_NUM_STATS ARRAY_SIZE(ldpaa_eth_dpni_stat_strings) + struct ldpaa_eth_priv { struct phy_device *phy; int phy_mode; @@ -129,6 +156,9 @@ struct ldpaa_eth_priv { uint16_t tx_flow_id;
enum ldpaa_eth_type type; /* 1G or 10G ethernet */ + + /* SW kept statistics */ + u64 dpni_stats[LDPAA_ETH_DPNI_NUM_STATS]; };
struct dprc_endpoint dpmac_endpoint;

On Tue, May 23, 2023 at 4:48 PM Ioana Ciornei ioana.ciornei@nxp.com wrote:
The ldpaa_eth driver already had a DPNI statistics dump, this patch extends the list of stats and adds a bit more structure to the code.
For a bit more context, the DPAA2 u-boot software architecture uses a default network interface object - a DPNI - which, at runtime, will get connected to the currently used DPMAC object. Each time the .stop() eth callback is called, the DPNI is reset to its original state, including its counters.
As a preparation for the next patches, we add a software kept set of DPNI counters which will get updated before each reset operation takes place.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com
drivers/net/ldpaa_eth/ldpaa_eth.c | 106 +++++++++++++++--------------- drivers/net/ldpaa_eth/ldpaa_eth.h | 30 +++++++++ 2 files changed, 82 insertions(+), 54 deletions(-)
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index fe901baf5a4e..907e51da6e1e 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -38,68 +38,56 @@ static void init_phy(struct udevice *dev) } #endif
-#ifdef DEBUG +static void ldpaa_eth_collect_dpni_stats(struct udevice *dev, u64 *data) +{
union dpni_statistics dpni_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),
};
int j, k, num_cnt, err, i = 0;
-#define DPNI_STATS_PER_PAGE 6
-static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = {
{
"DPNI_CNT_ING_ALL_FRAMES",
"DPNI_CNT_ING_ALL_BYTES",
"DPNI_CNT_ING_MCAST_FRAMES",
"DPNI_CNT_ING_MCAST_BYTES",
"DPNI_CNT_ING_BCAST_FRAMES",
"DPNI_CNT_ING_BCAST_BYTES",
}, {
"DPNI_CNT_EGR_ALL_FRAMES",
"DPNI_CNT_EGR_ALL_BYTES",
"DPNI_CNT_EGR_MCAST_FRAMES",
"DPNI_CNT_EGR_MCAST_BYTES",
"DPNI_CNT_EGR_BCAST_FRAMES",
"DPNI_CNT_EGR_BCAST_BYTES",
}, {
"DPNI_CNT_ING_FILTERED_FRAMES",
"DPNI_CNT_ING_DISCARDED_FRAMES",
"DPNI_CNT_ING_NOBUFFER_DISCARDS",
"DPNI_CNT_EGR_DISCARDED_FRAMES",
"DPNI_CNT_EGR_CNF_FRAMES",
""
},
-};
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(dflt_mc_io, MC_CMD_NO_FLAGS,
dflt_dpni->dpni_handle,
j, &dpni_stats);
if (err) {
memset(&dpni_stats, 0, sizeof(dpni_stats));
printf("dpni_get_stats(%d) failed\n", j);
}
num_cnt = dpni_stats_page_size[j] / sizeof(u64);
for (k = 0; k < num_cnt; k++)
*(data + i++) = dpni_stats.raw.counter[k];
}
+}
-static void print_dpni_stats(const char *strings[],
union dpni_statistics dpni_stats)
+static void ldpaa_eth_add_dpni_stats(struct udevice *dev, u64 *data) {
uint64_t *stat;
struct ldpaa_eth_priv *priv = dev_get_priv(dev); int i;
stat = (uint64_t *)&dpni_stats;
for (i = 0; i < DPNI_STATS_PER_PAGE; i++) {
if (strcmp(strings[i], "\0") == 0)
break;
printf("%s= %llu\n", strings[i], *stat);
stat++;
}
for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++)
priv->dpni_stats[i] += data[i];
}
-static void ldpaa_eth_get_dpni_counter(void) +#ifdef DEBUG
+static void ldpaa_eth_dump_dpni_stats(struct udevice *dev, u64 *data) {
int err = 0;
unsigned int page = 0;
union dpni_statistics dpni_stats;
int i;
printf("DPNI counters ..\n");
for (page = 0; page < 3; page++) {
err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS,
dflt_dpni->dpni_handle, page,
&dpni_stats);
if (err < 0) {
printf("dpni_get_statistics: failed:");
printf("%d for page[%d]\n", err, page);
return;
}
print_dpni_stats(dpni_statistics[page], dpni_stats);
}
printf("DPNI counters:\n");
for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++)
printf(" %s: %llu\n", ldpaa_eth_dpni_stat_strings[i], data[i]);
}
static void ldpaa_eth_get_dpmac_counter(struct udevice *dev) @@ -556,12 +544,22 @@ static void ldpaa_eth_stop(struct udevice *dev) struct ldpaa_eth_priv *priv = dev_get_priv(dev); struct phy_device *phydev = NULL; int err = 0;
u64 *data; if (!eth_is_active(dev)) return;
data = kzalloc(sizeof(u64) * LDPAA_ETH_DPNI_NUM_STATS, GFP_KERNEL);
if (data) {
ldpaa_eth_collect_dpni_stats(dev, data);
ldpaa_eth_add_dpni_stats(dev, data);
+#ifdef DEBUG
ldpaa_eth_dump_dpni_stats(dev, data);
+#endif
}
kfree(data);
#ifdef DEBUG
ldpaa_eth_get_dpni_counter(); ldpaa_eth_get_dpmac_counter(dev);
#endif
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h index 16d0106233e0..62dc9dd31029 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.h +++ b/drivers/net/ldpaa_eth/ldpaa_eth.h @@ -115,6 +115,33 @@ struct ldpaa_fas { LDPAA_ETH_FAS_MNLE | \ LDPAA_ETH_FAS_TIDE)
+static const char ldpaa_eth_dpni_stat_strings[][ETH_GSTRING_LEN] = {
"[dpni ] rx frames",
"[dpni ] rx bytes",
"[dpni ] rx mcast frames",
"[dpni ] rx mcast bytes",
"[dpni ] rx bcast frames",
"[dpni ] rx bcast bytes",
"[dpni ] tx frames",
"[dpni ] tx bytes",
"[dpni ] tx mcast frames",
"[dpni ] tx mcast bytes",
"[dpni ] tx bcast frames",
"[dpni ] tx bcast bytes",
"[dpni ] rx filtered frames",
"[dpni ] rx discarded frames",
"[dpni ] rx nobuffer discards",
"[dpni ] tx discarded frames",
"[dpni ] tx confirmed frames",
"[dpni ] tx dequeued bytes",
"[dpni ] tx dequeued frames",
"[dpni ] tx rejected bytes",
"[dpni ] tx rejected frames",
"[dpni ] tx pending frames",
+};
+#define LDPAA_ETH_DPNI_NUM_STATS ARRAY_SIZE(ldpaa_eth_dpni_stat_strings)
struct ldpaa_eth_priv { struct phy_device *phy; int phy_mode; @@ -129,6 +156,9 @@ struct ldpaa_eth_priv { uint16_t tx_flow_id;
enum ldpaa_eth_type type; /* 1G or 10G ethernet */
/* SW kept statistics */
u64 dpni_stats[LDPAA_ETH_DPNI_NUM_STATS];
};
struct dprc_endpoint dpmac_endpoint;
2.25.1
Reviewed-by: Ramon Fried rfried.dev@gmail.com

The ldpaa_eth driver already had a DPMAC statistics dump, this patch extends the list of stats and adds a bit more structure to the code.
For a bit more context, the DPAA2 u-boot software architecture uses a default network interface object - a DPNI - which, at runtime, will get connected to the currently used DPMAC object. Each time the .stop() eth callback is called, the DPMAC is destroyed thus any previous counters will get lost.
As a preparation for the next patches, we add a software kept set of DPMAC counters which will get updated before each destroy operation takes place.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com --- drivers/net/ldpaa_eth/ldpaa_eth.c | 114 ++++++++++-------------------- drivers/net/ldpaa_eth/ldpaa_eth.h | 34 +++++++++ include/fsl-mc/fsl_dpmac.h | 5 +- 3 files changed, 76 insertions(+), 77 deletions(-)
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 907e51da6e1e..53c5b8ba2b1d 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -79,8 +79,33 @@ static void ldpaa_eth_add_dpni_stats(struct udevice *dev, u64 *data) priv->dpni_stats[i] += data[i]; }
-#ifdef DEBUG +static void ldpaa_eth_collect_dpmac_stats(struct udevice *dev, u64 *data) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); + int err, i; + u64 value;
+ for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) { + err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, i, + &value); + if (err) + printf("dpmac_get_counter(%d) failed\n", i); + + *(data + i) = value; + } +} + +static void ldpaa_eth_add_dpmac_stats(struct udevice *dev, u64 *data) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); + int i; + + for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) + priv->dpmac_stats[i] += data[i]; +} + +#ifdef DEBUG static void ldpaa_eth_dump_dpni_stats(struct udevice *dev, u64 *data) { int i; @@ -90,82 +115,13 @@ static void ldpaa_eth_dump_dpni_stats(struct udevice *dev, u64 *data) printf(" %s: %llu\n", ldpaa_eth_dpni_stat_strings[i], data[i]); }
-static void ldpaa_eth_get_dpmac_counter(struct udevice *dev) +static void ldpaa_eth_dump_dpmac_stats(struct udevice *dev, u64 *data) { - struct ldpaa_eth_priv *priv = dev_get_priv(dev); - int err = 0; - u64 value; - - err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, - priv->dpmac_handle, - DPMAC_CNT_ING_BYTE, - &value); - if (err < 0) { - printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); - return; - } - printf("\nDPMAC counters ..\n"); - printf("DPMAC_CNT_ING_BYTE=%lld\n", value); - - err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, - priv->dpmac_handle, - DPMAC_CNT_ING_FRAME_DISCARD, - &value); - if (err < 0) { - printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n"); - return; - } - printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value); - - err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, - priv->dpmac_handle, - DPMAC_CNT_ING_ALIGN_ERR, - &value); - if (err < 0) { - printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n"); - return; - } - printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value); - - err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, - priv->dpmac_handle, - DPMAC_CNT_ING_BYTE, - &value); - if (err < 0) { - printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); - return; - } - printf("DPMAC_CNT_ING_BYTE=%lld\n", value); - - err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, - priv->dpmac_handle, - DPMAC_CNT_ING_ERR_FRAME, - &value); - if (err < 0) { - printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n"); - return; - } - printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value); - - err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, - priv->dpmac_handle, - DPMAC_CNT_EGR_BYTE , - &value); - if (err < 0) { - printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n"); - return; - } - printf("DPMAC_CNT_EGR_BYTE =%lld\n", value); + int i;
- err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, - priv->dpmac_handle, - DPMAC_CNT_EGR_ERR_FRAME , - &value); - if (err < 0) { - printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n"); - return; - } - printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value); + printf("DPMAC counters:\n"); + for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) + printf(" %s: %llu\n", ldpaa_eth_dpmac_stat_strings[i], data[i]); } #endif
@@ -559,9 +515,15 @@ static void ldpaa_eth_stop(struct udevice *dev) } kfree(data);
+ data = kzalloc(sizeof(u64) * LDPAA_ETH_DPMAC_NUM_STATS, GFP_KERNEL); + if (data) { + ldpaa_eth_collect_dpmac_stats(dev, data); + ldpaa_eth_add_dpmac_stats(dev, data); #ifdef DEBUG - ldpaa_eth_get_dpmac_counter(dev); + ldpaa_eth_dump_dpmac_stats(dev, data); #endif + } + kfree(data);
err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle, &dpmac_endpoint); diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h index 62dc9dd31029..af082e34caea 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.h +++ b/drivers/net/ldpaa_eth/ldpaa_eth.h @@ -142,6 +142,39 @@ static const char ldpaa_eth_dpni_stat_strings[][ETH_GSTRING_LEN] = {
#define LDPAA_ETH_DPNI_NUM_STATS ARRAY_SIZE(ldpaa_eth_dpni_stat_strings)
+static const char ldpaa_eth_dpmac_stat_strings[][ETH_GSTRING_LEN] = { + [DPMAC_CNT_ING_ALL_FRAME] = "[mac] rx all frames", + [DPMAC_CNT_ING_GOOD_FRAME] = "[mac] rx frames ok", + [DPMAC_CNT_ING_ERR_FRAME] = "[mac] rx frame errors", + [DPMAC_CNT_ING_FRAME_DISCARD] = "[mac] rx frame discards", + [DPMAC_CNT_ING_UCAST_FRAME] = "[mac] rx u-cast", + [DPMAC_CNT_ING_BCAST_FRAME] = "[mac] rx b-cast", + [DPMAC_CNT_ING_MCAST_FRAME] = "[mac] rx m-cast", + [DPMAC_CNT_ING_FRAME_64] = "[mac] rx 64 bytes", + [DPMAC_CNT_ING_FRAME_127] = "[mac] rx 65-127 bytes", + [DPMAC_CNT_ING_FRAME_255] = "[mac] rx 128-255 bytes", + [DPMAC_CNT_ING_FRAME_511] = "[mac] rx 256-511 bytes", + [DPMAC_CNT_ING_FRAME_1023] = "[mac] rx 512-1023 bytes", + [DPMAC_CNT_ING_FRAME_1518] = "[mac] rx 1024-1518 bytes", + [DPMAC_CNT_ING_FRAME_1519_MAX] = "[mac] rx 1519-max bytes", + [DPMAC_CNT_ING_FRAG] = "[mac] rx frags", + [DPMAC_CNT_ING_JABBER] = "[mac] rx jabber", + [DPMAC_CNT_ING_ALIGN_ERR] = "[mac] rx align errors", + [DPMAC_CNT_ING_OVERSIZED] = "[mac] rx oversized", + [DPMAC_CNT_ING_VALID_PAUSE_FRAME] = "[mac] rx pause", + [DPMAC_CNT_ING_BYTE] = "[mac] rx bytes", + [DPMAC_CNT_EGR_GOOD_FRAME] = "[mac] tx frames ok", + [DPMAC_CNT_EGR_UCAST_FRAME] = "[mac] tx u-cast", + [DPMAC_CNT_EGR_MCAST_FRAME] = "[mac] tx m-cast", + [DPMAC_CNT_EGR_BCAST_FRAME] = "[mac] tx b-cast", + [DPMAC_CNT_EGR_ERR_FRAME] = "[mac] tx frame errors", + [DPMAC_CNT_EGR_UNDERSIZED] = "[mac] tx undersized", + [DPMAC_CNT_EGR_VALID_PAUSE_FRAME] = "[mac] tx b-pause", + [DPMAC_CNT_EGR_BYTE] = "[mac] tx bytes", +}; + +#define LDPAA_ETH_DPMAC_NUM_STATS ARRAY_SIZE(ldpaa_eth_dpmac_stat_strings) + struct ldpaa_eth_priv { struct phy_device *phy; int phy_mode; @@ -159,6 +192,7 @@ struct ldpaa_eth_priv {
/* SW kept statistics */ u64 dpni_stats[LDPAA_ETH_DPNI_NUM_STATS]; + u64 dpmac_stats[LDPAA_ETH_DPMAC_NUM_STATS]; };
struct dprc_endpoint dpmac_endpoint; diff --git a/include/fsl-mc/fsl_dpmac.h b/include/fsl-mc/fsl_dpmac.h index 8f5e17fe222a..1fa26ef3805a 100644 --- a/include/fsl-mc/fsl_dpmac.h +++ b/include/fsl-mc/fsl_dpmac.h @@ -412,6 +412,8 @@ int dpmac_set_link_state(struct fsl_mc_io *mc_io, * @DPMAC_CNT_EGR_ERR_FRAME: counts frame transmitted with an error * @DPMAC_CNT_ING_GOOD_FRAME: counts frame received without error, including * pause frames. + * @DPMAC_CNT_EGR_GOOD_FRAME: counts frames transmitted without error, including + * pause frames. */ enum dpmac_counter { DPMAC_CNT_ING_FRAME_64, @@ -440,7 +442,8 @@ enum dpmac_counter { DPMAC_CNT_EGR_BCAST_FRAME, DPMAC_CNT_EGR_UCAST_FRAME, DPMAC_CNT_EGR_ERR_FRAME, - DPMAC_CNT_ING_GOOD_FRAME + DPMAC_CNT_ING_GOOD_FRAME, + DPMAC_CNT_EGR_GOOD_FRAME, };
/**

On Tue, May 23, 2023 at 4:48 PM Ioana Ciornei ioana.ciornei@nxp.com wrote:
The ldpaa_eth driver already had a DPMAC statistics dump, this patch extends the list of stats and adds a bit more structure to the code.
For a bit more context, the DPAA2 u-boot software architecture uses a default network interface object - a DPNI - which, at runtime, will get connected to the currently used DPMAC object. Each time the .stop() eth callback is called, the DPMAC is destroyed thus any previous counters will get lost.
As a preparation for the next patches, we add a software kept set of DPMAC counters which will get updated before each destroy operation takes place.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com
drivers/net/ldpaa_eth/ldpaa_eth.c | 114 ++++++++++-------------------- drivers/net/ldpaa_eth/ldpaa_eth.h | 34 +++++++++ include/fsl-mc/fsl_dpmac.h | 5 +- 3 files changed, 76 insertions(+), 77 deletions(-)
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 907e51da6e1e..53c5b8ba2b1d 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -79,8 +79,33 @@ static void ldpaa_eth_add_dpni_stats(struct udevice *dev, u64 *data) priv->dpni_stats[i] += data[i]; }
-#ifdef DEBUG +static void ldpaa_eth_collect_dpmac_stats(struct udevice *dev, u64 *data) +{
struct ldpaa_eth_priv *priv = dev_get_priv(dev);
int err, i;
u64 value;
for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) {
err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
priv->dpmac_handle, i,
&value);
if (err)
printf("dpmac_get_counter(%d) failed\n", i);
*(data + i) = value;
}
+}
+static void ldpaa_eth_add_dpmac_stats(struct udevice *dev, u64 *data) +{
struct ldpaa_eth_priv *priv = dev_get_priv(dev);
int i;
for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++)
priv->dpmac_stats[i] += data[i];
+}
+#ifdef DEBUG static void ldpaa_eth_dump_dpni_stats(struct udevice *dev, u64 *data) { int i; @@ -90,82 +115,13 @@ static void ldpaa_eth_dump_dpni_stats(struct udevice *dev, u64 *data) printf(" %s: %llu\n", ldpaa_eth_dpni_stat_strings[i], data[i]); }
-static void ldpaa_eth_get_dpmac_counter(struct udevice *dev) +static void ldpaa_eth_dump_dpmac_stats(struct udevice *dev, u64 *data) {
struct ldpaa_eth_priv *priv = dev_get_priv(dev);
int err = 0;
u64 value;
err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
priv->dpmac_handle,
DPMAC_CNT_ING_BYTE,
&value);
if (err < 0) {
printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
return;
}
printf("\nDPMAC counters ..\n");
printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
priv->dpmac_handle,
DPMAC_CNT_ING_FRAME_DISCARD,
&value);
if (err < 0) {
printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n");
return;
}
printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value);
err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
priv->dpmac_handle,
DPMAC_CNT_ING_ALIGN_ERR,
&value);
if (err < 0) {
printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n");
return;
}
printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value);
err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
priv->dpmac_handle,
DPMAC_CNT_ING_BYTE,
&value);
if (err < 0) {
printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
return;
}
printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
priv->dpmac_handle,
DPMAC_CNT_ING_ERR_FRAME,
&value);
if (err < 0) {
printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n");
return;
}
printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value);
err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
priv->dpmac_handle,
DPMAC_CNT_EGR_BYTE ,
&value);
if (err < 0) {
printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n");
return;
}
printf("DPMAC_CNT_EGR_BYTE =%lld\n", value);
int i;
err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
priv->dpmac_handle,
DPMAC_CNT_EGR_ERR_FRAME ,
&value);
if (err < 0) {
printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n");
return;
}
printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value);
printf("DPMAC counters:\n");
for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++)
printf(" %s: %llu\n", ldpaa_eth_dpmac_stat_strings[i], data[i]);
} #endif
@@ -559,9 +515,15 @@ static void ldpaa_eth_stop(struct udevice *dev) } kfree(data);
data = kzalloc(sizeof(u64) * LDPAA_ETH_DPMAC_NUM_STATS, GFP_KERNEL);
if (data) {
ldpaa_eth_collect_dpmac_stats(dev, data);
ldpaa_eth_add_dpmac_stats(dev, data);
#ifdef DEBUG
ldpaa_eth_get_dpmac_counter(dev);
ldpaa_eth_dump_dpmac_stats(dev, data);
#endif
}
kfree(data); err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle, &dpmac_endpoint);
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h index 62dc9dd31029..af082e34caea 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.h +++ b/drivers/net/ldpaa_eth/ldpaa_eth.h @@ -142,6 +142,39 @@ static const char ldpaa_eth_dpni_stat_strings[][ETH_GSTRING_LEN] = {
#define LDPAA_ETH_DPNI_NUM_STATS ARRAY_SIZE(ldpaa_eth_dpni_stat_strings)
+static const char ldpaa_eth_dpmac_stat_strings[][ETH_GSTRING_LEN] = {
[DPMAC_CNT_ING_ALL_FRAME] = "[mac] rx all frames",
[DPMAC_CNT_ING_GOOD_FRAME] = "[mac] rx frames ok",
[DPMAC_CNT_ING_ERR_FRAME] = "[mac] rx frame errors",
[DPMAC_CNT_ING_FRAME_DISCARD] = "[mac] rx frame discards",
[DPMAC_CNT_ING_UCAST_FRAME] = "[mac] rx u-cast",
[DPMAC_CNT_ING_BCAST_FRAME] = "[mac] rx b-cast",
[DPMAC_CNT_ING_MCAST_FRAME] = "[mac] rx m-cast",
[DPMAC_CNT_ING_FRAME_64] = "[mac] rx 64 bytes",
[DPMAC_CNT_ING_FRAME_127] = "[mac] rx 65-127 bytes",
[DPMAC_CNT_ING_FRAME_255] = "[mac] rx 128-255 bytes",
[DPMAC_CNT_ING_FRAME_511] = "[mac] rx 256-511 bytes",
[DPMAC_CNT_ING_FRAME_1023] = "[mac] rx 512-1023 bytes",
[DPMAC_CNT_ING_FRAME_1518] = "[mac] rx 1024-1518 bytes",
[DPMAC_CNT_ING_FRAME_1519_MAX] = "[mac] rx 1519-max bytes",
[DPMAC_CNT_ING_FRAG] = "[mac] rx frags",
[DPMAC_CNT_ING_JABBER] = "[mac] rx jabber",
[DPMAC_CNT_ING_ALIGN_ERR] = "[mac] rx align errors",
[DPMAC_CNT_ING_OVERSIZED] = "[mac] rx oversized",
[DPMAC_CNT_ING_VALID_PAUSE_FRAME] = "[mac] rx pause",
[DPMAC_CNT_ING_BYTE] = "[mac] rx bytes",
[DPMAC_CNT_EGR_GOOD_FRAME] = "[mac] tx frames ok",
[DPMAC_CNT_EGR_UCAST_FRAME] = "[mac] tx u-cast",
[DPMAC_CNT_EGR_MCAST_FRAME] = "[mac] tx m-cast",
[DPMAC_CNT_EGR_BCAST_FRAME] = "[mac] tx b-cast",
[DPMAC_CNT_EGR_ERR_FRAME] = "[mac] tx frame errors",
[DPMAC_CNT_EGR_UNDERSIZED] = "[mac] tx undersized",
[DPMAC_CNT_EGR_VALID_PAUSE_FRAME] = "[mac] tx b-pause",
[DPMAC_CNT_EGR_BYTE] = "[mac] tx bytes",
+};
+#define LDPAA_ETH_DPMAC_NUM_STATS ARRAY_SIZE(ldpaa_eth_dpmac_stat_strings)
struct ldpaa_eth_priv { struct phy_device *phy; int phy_mode; @@ -159,6 +192,7 @@ struct ldpaa_eth_priv {
/* SW kept statistics */ u64 dpni_stats[LDPAA_ETH_DPNI_NUM_STATS];
u64 dpmac_stats[LDPAA_ETH_DPMAC_NUM_STATS];
};
struct dprc_endpoint dpmac_endpoint; diff --git a/include/fsl-mc/fsl_dpmac.h b/include/fsl-mc/fsl_dpmac.h index 8f5e17fe222a..1fa26ef3805a 100644 --- a/include/fsl-mc/fsl_dpmac.h +++ b/include/fsl-mc/fsl_dpmac.h @@ -412,6 +412,8 @@ int dpmac_set_link_state(struct fsl_mc_io *mc_io,
- @DPMAC_CNT_EGR_ERR_FRAME: counts frame transmitted with an error
- @DPMAC_CNT_ING_GOOD_FRAME: counts frame received without error, including
pause frames.
- @DPMAC_CNT_EGR_GOOD_FRAME: counts frames transmitted without error, including
*/
pause frames.
enum dpmac_counter { DPMAC_CNT_ING_FRAME_64, @@ -440,7 +442,8 @@ enum dpmac_counter { DPMAC_CNT_EGR_BCAST_FRAME, DPMAC_CNT_EGR_UCAST_FRAME, DPMAC_CNT_EGR_ERR_FRAME,
DPMAC_CNT_ING_GOOD_FRAME
DPMAC_CNT_ING_GOOD_FRAME,
DPMAC_CNT_EGR_GOOD_FRAME,
};
/**
2.25.1
Reviewed-by: Ramon Fried rfried.dev@gmail.com

Add a new option to the 'net' command which can be used to dump network statistics.
To do this, 3 new callbacks are added to the eth_ops structure: .get_sset_count(), .get_strings(), .get_stats(). These callbacks have the same functions as in Linux: to return the number of counters, the strings which describe those counters and the actual values.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com --- cmd/net.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- include/net.h | 6 ++++++ 2 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/cmd/net.c b/cmd/net.c index 68d406291ef1..dfe811f41acf 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -13,6 +13,7 @@ #include <bootstage.h> #include <command.h> #include <dm.h> +#include <dm/devres.h> #include <env.h> #include <image.h> #include <log.h> @@ -691,8 +692,58 @@ static int do_net_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const ar return CMD_RET_SUCCESS; }
+static int do_net_stats(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + int nstats, err, i, off; + struct udevice *dev; + u64 *values; + u8 *strings; + + if (argc < 2) + return CMD_RET_USAGE; + + err = uclass_get_device_by_name(UCLASS_ETH, argv[1], &dev); + if (err) { + printf("Could not find device %s\n", argv[1]); + return CMD_RET_FAILURE; + } + + if (!eth_get_ops(dev)->get_sset_count || + !eth_get_ops(dev)->get_strings || + !eth_get_ops(dev)->get_stats) { + printf("Driver does not implement stats dump!\n"); + return CMD_RET_FAILURE; + } + + nstats = eth_get_ops(dev)->get_sset_count(dev); + strings = kcalloc(nstats, ETH_GSTRING_LEN, GFP_KERNEL); + if (!strings) + return CMD_RET_FAILURE; + + values = kcalloc(nstats, sizeof(u64), GFP_KERNEL); + if (!values) + goto err_free_strings; + + eth_get_ops(dev)->get_strings(dev, strings); + eth_get_ops(dev)->get_stats(dev, values); + + off = 0; + for (i = 0; i < nstats; i++) { + printf(" %s: %llu\n", &strings[off], values[i]); + off += ETH_GSTRING_LEN; + }; + + return CMD_RET_SUCCESS; + +err_free_strings: + kfree(strings); + + return CMD_RET_FAILURE; +} + static struct cmd_tbl cmd_net[] = { U_BOOT_CMD_MKENT(list, 1, 0, do_net_list, "", ""), + U_BOOT_CMD_MKENT(stats, 2, 0, do_net_stats, "", ""), };
static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -714,9 +765,10 @@ static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) }
U_BOOT_CMD( - net, 2, 1, do_net, + net, 3, 1, do_net, "NET sub-system", "list - list available devices\n" + "stats <device> - dump statistics for specified device\n" );
#if defined(CONFIG_CMD_NCSI) diff --git a/include/net.h b/include/net.h index 785cb1059ef9..e254df7d7f43 100644 --- a/include/net.h +++ b/include/net.h @@ -167,6 +167,9 @@ enum eth_recv_flags { * to the network stack. This function should fill in the * eth_pdata::enetaddr field - optional * set_promisc: Enable or Disable promiscuous mode + * get_sset_count: Number of statistics counters + * get_string: Names of the statistic counters + * get_stats: The values of the statistic counters */ struct eth_ops { int (*start)(struct udevice *dev); @@ -178,6 +181,9 @@ struct eth_ops { int (*write_hwaddr)(struct udevice *dev); int (*read_rom_hwaddr)(struct udevice *dev); int (*set_promisc)(struct udevice *dev, bool enable); + int (*get_sset_count)(struct udevice *dev); + void (*get_strings)(struct udevice *dev, u8 *data); + void (*get_stats)(struct udevice *dev, u64 *data); };
#define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops)

On Tue, May 23, 2023 at 4:48 PM Ioana Ciornei ioana.ciornei@nxp.com wrote:
Add a new option to the 'net' command which can be used to dump network statistics.
To do this, 3 new callbacks are added to the eth_ops structure: .get_sset_count(), .get_strings(), .get_stats(). These callbacks have the same functions as in Linux: to return the number of counters, the strings which describe those counters and the actual values.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com
cmd/net.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- include/net.h | 6 ++++++ 2 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/cmd/net.c b/cmd/net.c index 68d406291ef1..dfe811f41acf 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -13,6 +13,7 @@ #include <bootstage.h> #include <command.h> #include <dm.h> +#include <dm/devres.h> #include <env.h> #include <image.h> #include <log.h> @@ -691,8 +692,58 @@ static int do_net_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const ar return CMD_RET_SUCCESS; }
+static int do_net_stats(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{
int nstats, err, i, off;
struct udevice *dev;
u64 *values;
u8 *strings;
if (argc < 2)
return CMD_RET_USAGE;
err = uclass_get_device_by_name(UCLASS_ETH, argv[1], &dev);
if (err) {
printf("Could not find device %s\n", argv[1]);
return CMD_RET_FAILURE;
}
if (!eth_get_ops(dev)->get_sset_count ||
!eth_get_ops(dev)->get_strings ||
!eth_get_ops(dev)->get_stats) {
printf("Driver does not implement stats dump!\n");
return CMD_RET_FAILURE;
}
nstats = eth_get_ops(dev)->get_sset_count(dev);
strings = kcalloc(nstats, ETH_GSTRING_LEN, GFP_KERNEL);
if (!strings)
return CMD_RET_FAILURE;
values = kcalloc(nstats, sizeof(u64), GFP_KERNEL);
if (!values)
goto err_free_strings;
eth_get_ops(dev)->get_strings(dev, strings);
eth_get_ops(dev)->get_stats(dev, values);
off = 0;
for (i = 0; i < nstats; i++) {
printf(" %s: %llu\n", &strings[off], values[i]);
off += ETH_GSTRING_LEN;
};
return CMD_RET_SUCCESS;
+err_free_strings:
kfree(strings);
return CMD_RET_FAILURE;
+}
static struct cmd_tbl cmd_net[] = { U_BOOT_CMD_MKENT(list, 1, 0, do_net_list, "", ""),
U_BOOT_CMD_MKENT(stats, 2, 0, do_net_stats, "", ""),
};
static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -714,9 +765,10 @@ static int do_net(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) }
U_BOOT_CMD(
net, 2, 1, do_net,
net, 3, 1, do_net, "NET sub-system", "list - list available devices\n"
"stats <device> - dump statistics for specified device\n"
);
#if defined(CONFIG_CMD_NCSI) diff --git a/include/net.h b/include/net.h index 785cb1059ef9..e254df7d7f43 100644 --- a/include/net.h +++ b/include/net.h @@ -167,6 +167,9 @@ enum eth_recv_flags {
to the network stack. This function should fill in the
eth_pdata::enetaddr field - optional
- set_promisc: Enable or Disable promiscuous mode
- get_sset_count: Number of statistics counters
- get_string: Names of the statistic counters
*/
- get_stats: The values of the statistic counters
struct eth_ops { int (*start)(struct udevice *dev); @@ -178,6 +181,9 @@ struct eth_ops { int (*write_hwaddr)(struct udevice *dev); int (*read_rom_hwaddr)(struct udevice *dev); int (*set_promisc)(struct udevice *dev, bool enable);
int (*get_sset_count)(struct udevice *dev);
void (*get_strings)(struct udevice *dev, u8 *data);
void (*get_stats)(struct udevice *dev, u64 *data);
};
#define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops)
2.25.1
Reviewed-by: Ramon Fried rfried.dev@gmail.com

Export the already existing DPNI and DPMAC counters through the newly added callbacks.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com --- drivers/net/ldpaa_eth/ldpaa_eth.c | 44 ++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 53c5b8ba2b1d..8c0b5a3b6fd2 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -998,11 +998,47 @@ static int ldpaa_eth_of_to_plat(struct udevice *dev) return 0; }
+static int ldpaa_eth_get_sset_count(struct udevice *dev) +{ + return LDPAA_ETH_DPNI_NUM_STATS + LDPAA_ETH_DPMAC_NUM_STATS; +} + +static void ldpaa_eth_get_strings(struct udevice *dev, u8 *data) +{ + u8 *p = data; + int i; + + for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++) { + strlcpy(p, ldpaa_eth_dpni_stat_strings[i], ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } + + for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) { + strlcpy(p, ldpaa_eth_dpmac_stat_strings[i], ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } +} + +static void ldpaa_eth_get_stats(struct udevice *dev, u64 *data) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); + int i, j = 0; + + for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++) + *(data + j++) = priv->dpni_stats[i]; + + for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) + *(data + j++) = priv->dpmac_stats[i]; +} + static const struct eth_ops ldpaa_eth_ops = { - .start = ldpaa_eth_open, - .send = ldpaa_eth_tx, - .recv = ldpaa_eth_pull_dequeue_rx, - .stop = ldpaa_eth_stop, + .start = ldpaa_eth_open, + .send = ldpaa_eth_tx, + .recv = ldpaa_eth_pull_dequeue_rx, + .stop = ldpaa_eth_stop, + .get_sset_count = ldpaa_eth_get_sset_count, + .get_strings = ldpaa_eth_get_strings, + .get_stats = ldpaa_eth_get_stats, };
static const struct udevice_id ldpaa_eth_of_ids[] = {

On Tue, May 23, 2023 at 4:48 PM Ioana Ciornei ioana.ciornei@nxp.com wrote:
Export the already existing DPNI and DPMAC counters through the newly added callbacks.
Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com
drivers/net/ldpaa_eth/ldpaa_eth.c | 44 ++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 53c5b8ba2b1d..8c0b5a3b6fd2 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -998,11 +998,47 @@ static int ldpaa_eth_of_to_plat(struct udevice *dev) return 0; }
+static int ldpaa_eth_get_sset_count(struct udevice *dev) +{
return LDPAA_ETH_DPNI_NUM_STATS + LDPAA_ETH_DPMAC_NUM_STATS;
+}
+static void ldpaa_eth_get_strings(struct udevice *dev, u8 *data) +{
u8 *p = data;
int i;
for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++) {
strlcpy(p, ldpaa_eth_dpni_stat_strings[i], ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++) {
strlcpy(p, ldpaa_eth_dpmac_stat_strings[i], ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
+}
+static void ldpaa_eth_get_stats(struct udevice *dev, u64 *data) +{
struct ldpaa_eth_priv *priv = dev_get_priv(dev);
int i, j = 0;
for (i = 0; i < LDPAA_ETH_DPNI_NUM_STATS; i++)
*(data + j++) = priv->dpni_stats[i];
for (i = 0; i < LDPAA_ETH_DPMAC_NUM_STATS; i++)
*(data + j++) = priv->dpmac_stats[i];
+}
static const struct eth_ops ldpaa_eth_ops = {
.start = ldpaa_eth_open,
.send = ldpaa_eth_tx,
.recv = ldpaa_eth_pull_dequeue_rx,
.stop = ldpaa_eth_stop,
.start = ldpaa_eth_open,
.send = ldpaa_eth_tx,
.recv = ldpaa_eth_pull_dequeue_rx,
.stop = ldpaa_eth_stop,
.get_sset_count = ldpaa_eth_get_sset_count,
.get_strings = ldpaa_eth_get_strings,
.get_stats = ldpaa_eth_get_stats,
};
static const struct udevice_id ldpaa_eth_of_ids[] = {
2.25.1
Reviewed-by: Ramon Fried rfried.dev@gmail.com

Hi Joe, Ramon
I see this patchset is delegated to me, would you take care this patchset or let me handle?
Thanks, Peng.
On 5/23/2023 9:47 PM, Ioana Ciornei wrote:
This patch set extends the 'net' command so that it can be used to dump network statistics on the available devices. The first user of this new API is the ldpaa_eth driver which, in the last patch, implements the 3 new callbacks added.
Since the ldpaa_eth driver already had some debug printing of counters, the first 4 patches are there to extend the existing list of counters and to reorganize the code so that it fits better with the new eth_ops callbacks.
Ioana Ciornei (6): net: ldpaa_eth: fix the memory layout of the dpmac_get_counters() API net: ldpaa_eth: transform dpni_statistics from a struct to a union net: ldpaa_eth: extend debug capabilities with DPNI statistics net: ldpaa_eth: extend debug capabilities with DPMAC statistics cmd: net: add a 'net stats' command to dump network statistics net: ldpaa_eth: export DPNI and DPMAC counters through 'net stats'
cmd/net.c | 54 ++++++- drivers/net/fsl-mc/dpni.c | 2 +- drivers/net/ldpaa_eth/ldpaa_eth.c | 248 +++++++++++++++--------------- drivers/net/ldpaa_eth/ldpaa_eth.h | 64 ++++++++ include/fsl-mc/fsl_dpmac.h | 7 +- include/fsl-mc/fsl_dpni.h | 143 ++++++++++++----- include/net.h | 6 + 7 files changed, 353 insertions(+), 171 deletions(-)
-- 2.25.1

On Wed, May 31, 2023 at 4:19 AM Peng Fan peng.fan@oss.nxp.com wrote:
Hi Joe, Ramon
I see this patchset is delegated to me, would you take care this patchset or let me handle?
Thanks, Peng.
On 5/23/2023 9:47 PM, Ioana Ciornei wrote:
This patch set extends the 'net' command so that it can be used to dump network statistics on the available devices. The first user of this new API is the ldpaa_eth driver which, in the last patch, implements the 3 new callbacks added.
Since the ldpaa_eth driver already had some debug printing of counters, the first 4 patches are there to extend the existing list of counters and to reorganize the code so that it fits better with the new eth_ops callbacks.
Ioana Ciornei (6): net: ldpaa_eth: fix the memory layout of the dpmac_get_counters() API net: ldpaa_eth: transform dpni_statistics from a struct to a union net: ldpaa_eth: extend debug capabilities with DPNI statistics net: ldpaa_eth: extend debug capabilities with DPMAC statistics cmd: net: add a 'net stats' command to dump network statistics net: ldpaa_eth: export DPNI and DPMAC counters through 'net stats'
cmd/net.c | 54 ++++++- drivers/net/fsl-mc/dpni.c | 2 +- drivers/net/ldpaa_eth/ldpaa_eth.c | 248 +++++++++++++++--------------- drivers/net/ldpaa_eth/ldpaa_eth.h | 64 ++++++++ include/fsl-mc/fsl_dpmac.h | 7 +- include/fsl-mc/fsl_dpni.h | 143 ++++++++++++----- include/net.h | 6 + 7 files changed, 353 insertions(+), 171 deletions(-)
-- 2.25.1
Hi Peng, I reviewed everything. Tom will pick this up. Thanks, Ramon
participants (3)
-
Ioana Ciornei
-
Peng Fan
-
Ramon Fried