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