1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2022 Intel Corporation
*/
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include "rte_ethdev.h"
#include <rte_common.h>
#include "sff_telemetry.h"
#include <telemetry_data.h>
static void
sff_port_module_eeprom_parse(uint16_t port_id, struct rte_tel_data *d)
{
struct rte_eth_dev_module_info minfo;
struct rte_dev_eeprom_info einfo;
int ret;
if (d == NULL) {
RTE_ETHDEV_LOG_LINE(ERR, "Dict invalid");
return;
}
ret = rte_eth_dev_get_module_info(port_id, &minfo);
if (ret != 0) {
switch (ret) {
case -ENODEV:
RTE_ETHDEV_LOG_LINE(ERR, "Port index %d invalid", port_id);
break;
case -ENOTSUP:
RTE_ETHDEV_LOG_LINE(ERR, "Operation not supported by device");
break;
case -EIO:
RTE_ETHDEV_LOG_LINE(ERR, "Device is removed");
break;
default:
RTE_ETHDEV_LOG_LINE(ERR, "Unable to get port module info, %d", ret);
break;
}
return;
}
einfo.offset = 0;
einfo.length = minfo.eeprom_len;
einfo.data = calloc(1, minfo.eeprom_len);
if (einfo.data == NULL) {
RTE_ETHDEV_LOG_LINE(ERR, "Allocation of port %u EEPROM data failed", port_id);
return;
}
ret = rte_eth_dev_get_module_eeprom(port_id, &einfo);
if (ret != 0) {
switch (ret) {
case -ENODEV:
RTE_ETHDEV_LOG_LINE(ERR, "Port index %d invalid", port_id);
break;
case -ENOTSUP:
RTE_ETHDEV_LOG_LINE(ERR, "Operation not supported by device");
break;
case -EIO:
RTE_ETHDEV_LOG_LINE(ERR, "Device is removed");
break;
default:
RTE_ETHDEV_LOG_LINE(ERR, "Unable to get port module EEPROM, %d", ret);
break;
}
free(einfo.data);
return;
}
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);
break;
case RTE_ETH_MODULE_SFF_8472:
sff_8079_show_all(einfo.data, d);
sff_8472_show_all(einfo.data, d);
break;
case RTE_ETH_MODULE_SFF_8436:
case RTE_ETH_MODULE_SFF_8636:
sff_8636_show_all(einfo.data, einfo.length, d);
break;
default:
RTE_ETHDEV_LOG_LINE(NOTICE, "Unsupported module type: %u", minfo.type);
break;
}
free(einfo.data);
}
void
ssf_add_dict_string(struct rte_tel_data *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;
}
int
eth_dev_handle_port_module_eeprom(const char *cmd __rte_unused, const char *params,
struct rte_tel_data *d)
{
char *end_param;
uint64_t port_id;
if (params == NULL || strlen(params) == 0 || !isdigit(*params))
return -1;
errno = 0;
port_id = strtoul(params, &end_param, 0);
if (errno != 0 || port_id >= UINT16_MAX) {
RTE_ETHDEV_LOG_LINE(ERR, "Invalid argument, %d", errno);
return -1;
}
if (*end_param != '\0')
RTE_ETHDEV_LOG_LINE(NOTICE,
"Extra parameters [%s] passed to ethdev telemetry command, ignoring",
end_param);
rte_tel_data_start_dict(d);
sff_port_module_eeprom_parse(port_id, d);
return 0;
}
|