The SFF-8079, SFF-8472 and SFF-8636 decoders write their results
directly into a telemetry dictionary, so the decoding logic cannot
be reused outside of the telemetry command.

Introduce an internal output descriptor with a per-field callback
and pass it to the decoders instead of the telemetry data.
The telemetry handler becomes one of the callback consumers,
its output is unchanged.

Signed-off-by: Roman Khromenok <[email protected]>
---
 .mailmap                   |  1 +
 lib/ethdev/sff_8079.c      | 20 ++++++------
 lib/ethdev/sff_8472.c      |  2 +-
 lib/ethdev/sff_8636.c      | 22 ++++++-------
 lib/ethdev/sff_common.c    | 14 ++++----
 lib/ethdev/sff_common.h    | 14 ++++----
 lib/ethdev/sff_telemetry.c | 65 ++++++++++++++++++++------------------
 lib/ethdev/sff_telemetry.h | 15 ++++++---
 8 files changed, 83 insertions(+), 70 deletions(-)

diff --git a/.mailmap b/.mailmap
index 57f7a9f87a..45d4e92fbd 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1445,6 +1445,7 @@ Romain Delhomel <[email protected]>
 Roman Dementiev <[email protected]>
 Roman Fridlyand <[email protected]>
 Roman Kapl <[email protected]>
+Roman Khromenok <[email protected]>
 Roman Korynkevych <[email protected]>
 Roman Storozhenko <[email protected]>
 Roman Zhukov <[email protected]> <[email protected]>
diff --git a/lib/ethdev/sff_8079.c b/lib/ethdev/sff_8079.c
index 91ad25ffcd..a41a1d057d 100644
--- a/lib/ethdev/sff_8079.c
+++ b/lib/ethdev/sff_8079.c
@@ -7,12 +7,12 @@
 
 #include "sff_common.h"
 
-static void sff_8079_show_identifier(const uint8_t *data, struct rte_tel_data 
*d)
+static void sff_8079_show_identifier(const uint8_t *data, struct sff_output *d)
 {
        sff_8024_show_identifier(data, 0, d);
 }
 
-static void sff_8079_show_ext_identifier(const uint8_t *data, struct 
rte_tel_data *d)
+static void sff_8079_show_ext_identifier(const uint8_t *data, struct 
sff_output *d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
 
@@ -32,12 +32,12 @@ static void sff_8079_show_ext_identifier(const uint8_t 
*data, struct rte_tel_dat
        ssf_add_dict_string(d, "Extended identifier", val_string);
 }
 
-static void sff_8079_show_connector(const uint8_t *data, struct rte_tel_data 
*d)
+static void sff_8079_show_connector(const uint8_t *data, struct sff_output *d)
 {
        sff_8024_show_connector(data, 2, d);
 }
 
-static void sff_8079_show_transceiver(const uint8_t *data, struct rte_tel_data 
*d)
+static void sff_8079_show_transceiver(const uint8_t *data, struct sff_output 
*d)
 {
        static const char *name = "Transceiver type";
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
@@ -227,12 +227,12 @@ static void sff_8079_show_transceiver(const uint8_t 
*data, struct rte_tel_data *
        }
 }
 
-static void sff_8079_show_encoding(const uint8_t *data, struct rte_tel_data *d)
+static void sff_8079_show_encoding(const uint8_t *data, struct sff_output *d)
 {
        sff_8024_show_encoding(data, 11, RTE_ETH_MODULE_SFF_8472, d);
 }
 
-static void sff_8079_show_rate_identifier(const uint8_t *data, struct 
rte_tel_data *d)
+static void sff_8079_show_rate_identifier(const uint8_t *data, struct 
sff_output *d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
 
@@ -262,14 +262,14 @@ static void sff_8079_show_rate_identifier(const uint8_t 
*data, struct rte_tel_da
        ssf_add_dict_string(d, "Rate identifier", val_string);
 }
 
-static void sff_8079_show_oui(const uint8_t *data, struct rte_tel_data *d)
+static void sff_8079_show_oui(const uint8_t *data, struct sff_output *d)
 {
        sff_8024_show_oui(data, 37, d);
 }
 
 static void
 sff_8079_show_wavelength_or_copper_compliance(const uint8_t *data,
-                                             struct rte_tel_data *d)
+                                             struct sff_output *d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
 
@@ -312,7 +312,7 @@ sff_8079_show_wavelength_or_copper_compliance(const uint8_t 
*data,
        }
 }
 
-static void sff_8079_show_options(const uint8_t *data, struct rte_tel_data *d)
+static void sff_8079_show_options(const uint8_t *data, struct sff_output *d)
 {
        static const char *name = "Option";
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
@@ -348,7 +348,7 @@ static void sff_8079_show_options(const uint8_t *data, 
struct rte_tel_data *d)
                ssf_add_dict_string(d, name, "Power level 3 requirement");
 }
 
-void sff_8079_show_all(const uint8_t *data, struct rte_tel_data *d)
+void sff_8079_show_all(const uint8_t *data, struct sff_output *d)
 {
        sff_8079_show_identifier(data, d);
        if (((data[0] == 0x02) || (data[0] == 0x03)) && (data[1] == 0x04)) {
diff --git a/lib/ethdev/sff_8472.c b/lib/ethdev/sff_8472.c
index 97f231854c..2d02e71fca 100644
--- a/lib/ethdev/sff_8472.c
+++ b/lib/ethdev/sff_8472.c
@@ -231,7 +231,7 @@ static void sff_8472_parse_eeprom(const uint8_t *data, 
struct sff_diags *sd)
                sff_8472_calibration(data, sd);
 }
 
-void sff_8472_show_all(const uint8_t *data, struct rte_tel_data *d)
+void sff_8472_show_all(const uint8_t *data, struct sff_output *d)
 {
        struct sff_diags sd = {0};
        const char *rx_power_string = NULL;
diff --git a/lib/ethdev/sff_8636.c b/lib/ethdev/sff_8636.c
index 6b65f47efe..17058d4bfd 100644
--- a/lib/ethdev/sff_8636.c
+++ b/lib/ethdev/sff_8636.c
@@ -164,12 +164,12 @@ static struct sff_8636_aw_flags {
        { NULL, 0, 0 },
 };
 
-static void sff_8636_show_identifier(const uint8_t *data, struct rte_tel_data 
*d)
+static void sff_8636_show_identifier(const uint8_t *data, struct sff_output *d)
 {
        sff_8024_show_identifier(data, SFF_8636_ID_OFFSET, d);
 }
 
-static void sff_8636_show_ext_identifier(const uint8_t *data, struct 
rte_tel_data *d)
+static void sff_8636_show_ext_identifier(const uint8_t *data, struct 
sff_output *d)
 {
        static const char *name = "Extended identifier description";
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
@@ -224,12 +224,12 @@ static void sff_8636_show_ext_identifier(const uint8_t 
*data, struct rte_tel_dat
        ssf_add_dict_string(d, name, val_string);
 }
 
-static void sff_8636_show_connector(const uint8_t *data, struct rte_tel_data 
*d)
+static void sff_8636_show_connector(const uint8_t *data, struct sff_output *d)
 {
        sff_8024_show_connector(data, SFF_8636_CTOR_OFFSET, d);
 }
 
-static void sff_8636_show_transceiver(const uint8_t *data, struct rte_tel_data 
*d)
+static void sff_8636_show_transceiver(const uint8_t *data, struct sff_output 
*d)
 {
        static const char *name = "Transceiver type";
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
@@ -438,13 +438,13 @@ static void sff_8636_show_transceiver(const uint8_t 
*data, struct rte_tel_data *
                ssf_add_dict_string(d, name, "FC: 100 MBytes/sec");
 }
 
-static void sff_8636_show_encoding(const uint8_t *data, struct rte_tel_data *d)
+static void sff_8636_show_encoding(const uint8_t *data, struct sff_output *d)
 {
        sff_8024_show_encoding(data, SFF_8636_ENCODING_OFFSET,
                               RTE_ETH_MODULE_SFF_8636, d);
 }
 
-static void sff_8636_show_rate_identifier(const uint8_t *data, struct 
rte_tel_data *d)
+static void sff_8636_show_rate_identifier(const uint8_t *data, struct 
sff_output *d)
 {
        char val_string[20];
 
@@ -452,13 +452,13 @@ static void sff_8636_show_rate_identifier(const uint8_t 
*data, struct rte_tel_da
        ssf_add_dict_string(d, "Rate identifier", val_string);
 }
 
-static void sff_8636_show_oui(const uint8_t *data, struct rte_tel_data *d)
+static void sff_8636_show_oui(const uint8_t *data, struct sff_output *d)
 {
        sff_8024_show_oui(data, SFF_8636_VENDOR_OUI_OFFSET, d);
 }
 
 static void sff_8636_show_wavelength_or_copper_compliance(const uint8_t *data,
-                                                         struct rte_tel_data 
*d)
+                                                         struct sff_output *d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
        snprintf(val_string, sizeof(val_string), "0x%02x",
@@ -554,7 +554,7 @@ static void 
sff_8636_show_wavelength_or_copper_compliance(const uint8_t *data,
        }
 }
 
-static void sff_8636_show_revision_compliance(const uint8_t *data, struct 
rte_tel_data *d)
+static void sff_8636_show_revision_compliance(const uint8_t *data, struct 
sff_output *d)
 {
        static const char *name = "Revision Compliance";
 
@@ -638,7 +638,7 @@ static void sff_8636_dom_parse(const uint8_t *data, struct 
sff_diags *sd)
 
 }
 
-static void sff_8636_show_dom(const uint8_t *data, uint32_t eeprom_len, struct 
rte_tel_data *d)
+static void sff_8636_show_dom(const uint8_t *data, uint32_t eeprom_len, struct 
sff_output *d)
 {
        struct sff_diags sd = {0};
        const char *rx_power_string = NULL;
@@ -723,7 +723,7 @@ static void sff_8636_show_dom(const uint8_t *data, uint32_t 
eeprom_len, struct r
        }
 
 }
-void sff_8636_show_all(const uint8_t *data, uint32_t eeprom_len, struct 
rte_tel_data *d)
+void sff_8636_show_all(const uint8_t *data, uint32_t eeprom_len, struct 
sff_output *d)
 {
        sff_8636_show_identifier(data, d);
        if ((data[SFF_8636_ID_OFFSET] == SFF_8024_ID_QSFP) ||
diff --git a/lib/ethdev/sff_common.c b/lib/ethdev/sff_common.c
index bd425274e3..c80e841fd4 100644
--- a/lib/ethdev/sff_common.c
+++ b/lib/ethdev/sff_common.c
@@ -15,7 +15,7 @@ double sff_convert_mw_to_dbm(double mw)
 
 void sff_show_value_with_unit(const uint8_t *data, unsigned int reg,
                              const char *name, unsigned int mult,
-                             const char *unit, struct rte_tel_data *d)
+                             const char *unit, struct sff_output *d)
 {
        unsigned int val = data[reg];
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
@@ -25,7 +25,7 @@ void sff_show_value_with_unit(const uint8_t *data, unsigned 
int reg,
 }
 
 void sff_show_ascii(const uint8_t *data, unsigned int first_reg,
-                   unsigned int last_reg, const char *name, struct 
rte_tel_data *d)
+                   unsigned int last_reg, const char *name, struct sff_output 
*d)
 {
        unsigned int reg, val;
        char tmp[3];
@@ -47,7 +47,7 @@ void sff_show_ascii(const uint8_t *data, unsigned int 
first_reg,
        ssf_add_dict_string(d, name, val_string);
 }
 
-void sff_8024_show_oui(const uint8_t *data, int id_offset, struct rte_tel_data 
*d)
+void sff_8024_show_oui(const uint8_t *data, int id_offset, struct sff_output 
*d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
 
@@ -56,7 +56,7 @@ void sff_8024_show_oui(const uint8_t *data, int id_offset, 
struct rte_tel_data *
        ssf_add_dict_string(d, "Vendor OUI", val_string);
 }
 
-void sff_8024_show_identifier(const uint8_t *data, int id_offset, struct 
rte_tel_data *d)
+void sff_8024_show_identifier(const uint8_t *data, int id_offset, struct 
sff_output *d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
 
@@ -145,7 +145,7 @@ void sff_8024_show_identifier(const uint8_t *data, int 
id_offset, struct rte_tel
        ssf_add_dict_string(d, "Identifier", val_string);
 }
 
-void sff_8024_show_connector(const uint8_t *data, int ctor_offset, struct 
rte_tel_data *d)
+void sff_8024_show_connector(const uint8_t *data, int ctor_offset, struct 
sff_output *d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
 
@@ -217,7 +217,7 @@ void sff_8024_show_connector(const uint8_t *data, int 
ctor_offset, struct rte_te
 }
 
 void sff_8024_show_encoding(const uint8_t *data, int encoding_offset,
-                           int sff_type, struct rte_tel_data *d)
+                           int sff_type, struct sff_output *d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
 
@@ -268,7 +268,7 @@ void sff_8024_show_encoding(const uint8_t *data, int 
encoding_offset,
        ssf_add_dict_string(d, "Encoding", val_string);
 }
 
-void sff_show_thresholds(struct sff_diags sd, struct rte_tel_data *d)
+void sff_show_thresholds(struct sff_diags sd, struct sff_output *d)
 {
        char val_string[SFF_ITEM_VAL_COMPOSE_SIZE];
 
diff --git a/lib/ethdev/sff_common.h b/lib/ethdev/sff_common.h
index 2e42cbe8be..6a742e9d7b 100644
--- a/lib/ethdev/sff_common.h
+++ b/lib/ethdev/sff_common.h
@@ -158,15 +158,15 @@ struct sff_diags {
 double sff_convert_mw_to_dbm(double mw);
 void sff_show_value_with_unit(const uint8_t *data, unsigned int reg,
                              const char *name, unsigned int mult,
-                             const char *unit, struct rte_tel_data *d);
+                             const char *unit, struct sff_output *d);
 void sff_show_ascii(const uint8_t *data, unsigned int first_reg,
-                   unsigned int last_reg, const char *name, struct 
rte_tel_data *d);
-void sff_show_thresholds(struct sff_diags sd, struct rte_tel_data *d);
+                   unsigned int last_reg, const char *name, struct sff_output 
*d);
+void sff_show_thresholds(struct sff_diags sd, struct sff_output *d);
 
-void sff_8024_show_oui(const uint8_t *data, int id_offset, struct rte_tel_data 
*d);
-void sff_8024_show_identifier(const uint8_t *data, int id_offset, struct 
rte_tel_data *d);
-void sff_8024_show_connector(const uint8_t *data, int ctor_offset, struct 
rte_tel_data *d);
+void sff_8024_show_oui(const uint8_t *data, int id_offset, struct sff_output 
*d);
+void sff_8024_show_identifier(const uint8_t *data, int id_offset, struct 
sff_output *d);
+void sff_8024_show_connector(const uint8_t *data, int ctor_offset, struct 
sff_output *d);
 void sff_8024_show_encoding(const uint8_t *data, int encoding_offset,
-                           int sff_type, struct rte_tel_data *d);
+                           int sff_type, struct sff_output *d);
 
 #endif /* _SFF_COMMON_H_ */
diff --git a/lib/ethdev/sff_telemetry.c b/lib/ethdev/sff_telemetry.c
index b3f239d967..8c8e95affe 100644
--- a/lib/ethdev/sff_telemetry.c
+++ b/lib/ethdev/sff_telemetry.c
@@ -11,9 +11,38 @@
 #include "sff_telemetry.h"
 #include <telemetry_data.h>
 
+static void
+sff_tel_add_field(const char *name_str, const char *value_str, void *arg)
+{
+       struct rte_tel_data *d = arg;
+       struct tel_dict_entry *e = &d->data.dict[d->data_len];
+
+       if (d->type != TEL_DICT)
+               return;
+       if (d->data_len >= RTE_TEL_MAX_DICT_ENTRIES) {
+               RTE_ETHDEV_LOG_LINE(ERR, "data_len has exceeded the maximum 
number of inserts");
+               return;
+       }
+
+       e->type = RTE_TEL_STRING_VAL;
+       /* append different values for same keys */
+       if (d->data_len > 0) {
+               struct tel_dict_entry *previous = &d->data.dict[d->data_len - 
1];
+               if (strcmp(previous->name, name_str) == 0) {
+                       strlcat(previous->value.sval, "; ", 
RTE_TEL_MAX_STRING_LEN);
+                       strlcat(previous->value.sval, value_str, 
RTE_TEL_MAX_STRING_LEN);
+                       return;
+               }
+       }
+       strlcpy(e->value.sval, value_str, RTE_TEL_MAX_STRING_LEN);
+       strlcpy(e->name, name_str, RTE_TEL_MAX_STRING_LEN);
+       d->data_len++;
+}
+
 static void
 sff_port_module_eeprom_parse(uint16_t port_id, struct rte_tel_data *d)
 {
+       struct sff_output out = { .field_cb = sff_tel_add_field, .arg = d };
        struct rte_eth_dev_module_info minfo;
        struct rte_dev_eeprom_info einfo;
        int ret;
@@ -73,15 +102,15 @@ sff_port_module_eeprom_parse(uint16_t port_id, struct 
rte_tel_data *d)
        switch (minfo.type) {
        /* parsing module EEPROM data base on different module type */
        case RTE_ETH_MODULE_SFF_8079:
-               sff_8079_show_all(einfo.data, d);
+               sff_8079_show_all(einfo.data, &out);
                break;
        case RTE_ETH_MODULE_SFF_8472:
-               sff_8079_show_all(einfo.data, d);
-               sff_8472_show_all(einfo.data, d);
+               sff_8079_show_all(einfo.data, &out);
+               sff_8472_show_all(einfo.data, &out);
                break;
        case RTE_ETH_MODULE_SFF_8436:
        case RTE_ETH_MODULE_SFF_8636:
-               sff_8636_show_all(einfo.data, einfo.length, d);
+               sff_8636_show_all(einfo.data, einfo.length, &out);
                break;
        default:
                RTE_ETHDEV_LOG_LINE(NOTICE, "Unsupported module type: %u", 
minfo.type);
@@ -92,33 +121,9 @@ sff_port_module_eeprom_parse(uint16_t port_id, struct 
rte_tel_data *d)
 }
 
 void
-ssf_add_dict_string(struct rte_tel_data *d, const char *name_str, const char 
*value_str)
+ssf_add_dict_string(struct sff_output *d, const char *name_str, const char 
*value_str)
 {
-       struct tel_dict_entry *e = &d->data.dict[d->data_len];
-
-       if (d->type != TEL_DICT)
-               return;
-       if (d->data_len >= RTE_TEL_MAX_DICT_ENTRIES) {
-               RTE_ETHDEV_LOG_LINE(ERR, "data_len has exceeded the maximum 
number of inserts");
-               return;
-       }
-
-       e->type = RTE_TEL_STRING_VAL;
-       /* append different values for same keys */
-       if (d->data_len > 0) {
-               struct tel_dict_entry *previous = &d->data.dict[d->data_len - 
1];
-               if (strcmp(previous->name, name_str) == 0) {
-                       strlcat(previous->value.sval, "; ", 
RTE_TEL_MAX_STRING_LEN);
-                       strlcat(previous->value.sval, value_str, 
RTE_TEL_MAX_STRING_LEN);
-                       goto end;
-               }
-       }
-       strlcpy(e->value.sval, value_str, RTE_TEL_MAX_STRING_LEN);
-       strlcpy(e->name, name_str, RTE_TEL_MAX_STRING_LEN);
-       d->data_len++;
-
-end:
-       return;
+       d->field_cb(name_str, value_str, d->arg);
 }
 
 int
diff --git a/lib/ethdev/sff_telemetry.h b/lib/ethdev/sff_telemetry.h
index 81c1fb0ffb..2a6d79a9c1 100644
--- a/lib/ethdev/sff_telemetry.h
+++ b/lib/ethdev/sff_telemetry.h
@@ -9,20 +9,27 @@
 
 #define SFF_ITEM_VAL_COMPOSE_SIZE 64
 
+/* Consumer of decoded module EEPROM fields */
+struct sff_output {
+       /* Called once per decoded field, name may repeat */
+       void (*field_cb)(const char *name, const char *value, void *arg);
+       void *arg;
+};
+
 /* SFF-8079 Optics diagnostics */
-void sff_8079_show_all(const uint8_t *data, struct rte_tel_data *d);
+void sff_8079_show_all(const uint8_t *data, struct sff_output *d);
 
 /* SFF-8472 Optics diagnostics */
-void sff_8472_show_all(const uint8_t *data, struct rte_tel_data *d);
+void sff_8472_show_all(const uint8_t *data, struct sff_output *d);
 
 /* SFF-8636 Optics diagnostics */
-void sff_8636_show_all(const uint8_t *data, uint32_t eeprom_len, struct 
rte_tel_data *d);
+void sff_8636_show_all(const uint8_t *data, uint32_t eeprom_len, struct 
sff_output *d);
 
 int eth_dev_handle_port_module_eeprom(const char *cmd __rte_unused,
                                      const char *params,
                                      struct rte_tel_data *d);
 
-void ssf_add_dict_string(struct rte_tel_data *d, const char *name_str,
+void ssf_add_dict_string(struct sff_output *d, const char *name_str,
                         const char *value_str);
 
 #endif /* _ETHDEV_SFF_TELEMETRY_H_ */
-- 
2.47.3

Reply via email to