30 #define SWITCHTEC_LIB_CORE
32 #include "switchtec/pmon.h"
33 #include "switchtec_priv.h"
35 #include "switchtec/endian.h"
60 #define ENTRY(x, h) {.mask=x, .name=#x, .help=h}
63 ENTRY(
ALL,
"all events"),
83 ENTRY(
RCV_CORR_MSG,
"Correctable Error Message received"),
121 if ((t->mask & *type_mask) != t->mask)
124 *type_mask &= ~t->mask;
144 .sub_cmd_id = MRPC_PMON_SETUP_EV_COUNTER,
145 .stack_id = stack_id,
146 .counter_id = cntr_id,
151 .mask = htole32((setup->
type_mask << 8) |
152 (setup->port_mask & 0xFF)),
153 .ieg = setup->egress,
159 if (cntr_id >= SWITCHTEC_MAX_EVENT_COUNTERS) {
168 static int evcntr_get(
struct switchtec_dev *dev,
int sub_cmd,
169 unsigned stack_id,
unsigned cntr_id,
unsigned nr_cntrs,
170 void *res,
size_t res_size,
int clear)
175 .sub_cmd_id = sub_cmd,
176 .stack_id = stack_id,
177 .counter_id = cntr_id,
178 .num_counters = nr_cntrs,
182 if (res_size > MRPC_MAX_DATA_LEN ||
183 cntr_id >= SWITCHTEC_MAX_EVENT_COUNTERS ||
184 nr_cntrs > SWITCHTEC_MAX_EVENT_COUNTERS ||
185 cntr_id + nr_cntrs > SWITCHTEC_MAX_EVENT_COUNTERS)
215 unsigned cntr_id,
unsigned nr_cntrs,
227 ret = evcntr_get(dev, MRPC_PMON_GET_EV_COUNTER_SETUP,
228 stack_id, cntr_id, nr_cntrs, data,
229 sizeof(*data) * nr_cntrs, 0);
233 for (i = 0; i < nr_cntrs; i++) {
234 res[i].port_mask = le32toh(data[i].mask) & 0xFF;
235 res[i].
type_mask = le32toh(data[i].mask) >> 8;
236 res[i].egress = data[i].ieg;
237 res[i].
threshold = le32toh(data[i].thresh);
258 unsigned cntr_id,
unsigned nr_cntrs,
unsigned *res,
270 ret = evcntr_get(dev, MRPC_PMON_GET_EV_COUNTER,
271 stack_id, cntr_id, nr_cntrs, data,
272 sizeof(*data) * nr_cntrs, clear);
276 for (i = 0; i < nr_cntrs; i++)
277 res[i] = le32toh(data[i].value);
302 unsigned cntr_id,
unsigned nr_cntrs,
304 unsigned *counts,
int clear)
328 SWITCHTEC_EVT_IDX_ALL,
366 .sub_cmd_id = MRPC_PMON_SET_BW_COUNTER,
370 for (i = 0; i < cmd.count; i++) {
371 cmd.ports[i].id = phys_port_ids[i];
372 cmd.ports[i].bw_type = bw_type;
376 sizeof(cmd.ports[0]) * cmd.count;
378 return switchtec_cmd(dev, MRPC_PMON, &cmd, cmd_size, NULL, 0);
392 int ids[SWITCHTEC_MAX_PORTS];
398 for (i = 0; i < ret; i++) {
420 int *phys_port_ids,
int clear,
425 int remain = nr_ports;
428 .sub_cmd_id = MRPC_PMON_GET_BW_COUNTER,
430 int cmd_max_count = ((MRPC_MAX_DATA_LEN -
sizeof(
struct pmon_bw_get))
435 if (cmd.count > cmd_max_count)
436 cmd.count = cmd_max_count;
438 for (i = 0; i < cmd.count; i++) {
439 cmd.ports[i].id = phys_port_ids[i];
440 cmd.ports[i].clear = clear;
444 sizeof(cmd.ports[0]) * cmd.count;
447 sizeof(*res) * cmd.count);
452 phys_port_ids += cmd.count;
479 int ids[SWITCHTEC_MAX_PORTS];
486 *ports = calloc(ret,
sizeof(**ports));
488 *res = calloc(ret,
sizeof(**res));
490 for (i = 0; i < ret; i++) {
493 (*ports)[i] = status[i].
port;
515 return d->posted + d->nonposted + d->comp;
528 int *egress_port_ids,
int *ingress_port_ids)
533 .sub_cmd_id = MRPC_PMON_SETUP_LAT_COUNTER,
537 for (i = 0; i < nr_ports; i++) {
538 cmd.ports[i].egress = egress_port_ids[i];
539 cmd.ports[i].ingress = ingress_port_ids[i];
543 sizeof(cmd.ports[0]) * nr_ports;
545 return switchtec_cmd(dev, MRPC_PMON, &cmd, cmd_size, NULL, 0);
558 int ingress_port_id,
int clear)
586 int clear,
int *egress_port_ids,
587 int *cur_ns,
int *max_ns)
593 .sub_cmd_id = MRPC_PMON_GET_LAT_COUNTER,
598 for (i = 0; i < nr_ports; i++)
599 cmd.port_ids[i] = egress_port_ids[i];
602 sizeof(cmd.port_ids[0]) * nr_ports;
605 sizeof(*resp) * nr_ports);
611 for (i = 0; i < nr_ports; i++)
612 cur_ns[i] = resp[i].cur_ns;
615 for (i = 0; i < nr_ports; i++)
616 max_ns[i] = resp[i].max_ns;
634 int egress_port_ids,
int *cur_ns,