Mykola Zhuravel
2017-07-19 15:40:35 UTC
- support getting counters of port RX/TX messages
- support set(clear) counters of port RX/TX messages
Signed-off-by: Mykola Zhuravel <***@mellanox.com>
---
clock.c | 1 +
pmc.c | 45 ++++++++++++++++++++++++++++++++++++++
pmc_common.c | 3 +++
port.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tlv.c | 8 +++++++
tlv.h | 25 +++++++++++++++++++++
6 files changed, 153 insertions(+)
diff --git a/clock.c b/clock.c
index da15882..8c8ca9a 100644
--- a/clock.c
+++ b/clock.c
@@ -1303,6 +1303,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
switch (mgt->id) {
case TLV_PORT_PROPERTIES_NP:
+ case TLV_PORT_COUNTERS:
if (p != c->uds_port) {
/* Only the UDS port allowed. */
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
diff --git a/pmc.c b/pmc.c
index a991880..3067f16 100644
--- a/pmc.c
+++ b/pmc.c
@@ -108,6 +108,7 @@ struct management_id idtab[] = {
{ "LOG_MIN_PDELAY_REQ_INTERVAL", TLV_LOG_MIN_PDELAY_REQ_INTERVAL, do_get_action },
{ "PORT_DATA_SET_NP", TLV_PORT_DATA_SET_NP, do_set_action },
{ "PORT_PROPERTIES_NP", TLV_PORT_PROPERTIES_NP, do_get_action },
+ { "PORT_COUNTERS", TLV_PORT_COUNTERS, do_set_action},
};
static const char *action_string[] = {
@@ -198,6 +199,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
struct portDS *p;
struct port_ds_np *pnp;
struct port_properties_np *ppnp;
+ struct port_counters *pc;
if (msg_type(msg) != MANAGEMENT) {
return;
}
@@ -492,6 +494,39 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
pid2str(&ppnp->portIdentity), ps_str[ppnp->port_state],
ts_str[ppnp->timestamping], text2str(&ppnp->interface));
break;
+ case TLV_PORT_COUNTERS:
+ pc = (struct port_counters *) mgt->data;
+ fprintf(fp, "TLV_PORT_COUNTERS "
+ IFMT "interface %s"
+ IFMT "sync_rx_cnt %" PRIu64
+ IFMT "delay_req_rx_cnt %" PRIu64
+ IFMT "pdelay_req_rx_cnt %" PRIu64
+ IFMT "pdelay_resp_rx_cnt %" PRIu64
+ IFMT "follow_up_rx_cnt %" PRIu64
+ IFMT "delay_resp_rx_cnt %" PRIu64
+ IFMT "pdelay_resp_fup_rx_cnt %" PRIu64
+ IFMT "annonce_rx_cnt %" PRIu64
+ IFMT "signaling_rx_cnt %" PRIu64
+ IFMT "mgmtd_rx_cnt %" PRIu64
+ IFMT "sync_tx_cnt %" PRIu64
+ IFMT "delay_req_tx_cnt %" PRIu64
+ IFMT "pdelay_req_tx_cnt %" PRIu64
+ IFMT "pdelay_resp_tx_cnt %" PRIu64
+ IFMT "follow_up_tx_cnt %" PRIu64
+ IFMT "delay_resp_tx_cnt %" PRIu64
+ IFMT "pdelay_resp_fup_tx_cnt %" PRIu64
+ IFMT "annonce_tx_cnt %" PRIu64
+ IFMT "signaling_tx_cnt %" PRIu64
+ IFMT "mgmtd_tx_cnt %" PRIu64,
+ text2str(&pc->interface),
+ pc->sync_rx_cnt, pc->delay_req_rx_cnt, pc->pdelay_req_rx_cnt,
+ pc->pdelay_resp_rx_cnt, pc->follow_up_rx_cnt, pc->delay_resp_rx_cnt,
+ pc->pdelay_resp_fup_rx_cnt, pc->annonce_rx_cnt, pc->signaling_rx_cnt,
+ pc->mgmtd_rx_cnt, pc->sync_tx_cnt, pc->delay_req_tx_cnt, pc->pdelay_req_tx_cnt,
+ pc->pdelay_resp_tx_cnt, pc->follow_up_tx_cnt, pc->delay_resp_tx_cnt,
+ pc->pdelay_resp_fup_tx_cnt, pc->annonce_tx_cnt, pc->signaling_tx_cnt,
+ pc->mgmtd_tx_cnt);
+ break;
}
out:
fprintf(fp, "\n");
@@ -514,6 +549,8 @@ static void do_set_action(int action, int index, char *str)
int cnt, code = idtab[index].code;
int leap_61, leap_59, utc_off_valid;
int ptp_timescale, time_traceable, freq_traceable;
+ int pc_len;
+ struct port_counters pc;
switch (action) {
case GET:
@@ -597,6 +634,14 @@ static void do_set_action(int action, int index, char *str)
}
pmc_send_set_action(pmc, code, &pnp, sizeof(pnp));
break;
+ case TLV_PORT_COUNTERS:
+ pc_len = sizeof(pc);
+ memset(&pc, 0, pc_len);
+ if (pc_len % 2) {
+ pc_len++;
+ }
+ pmc_send_set_action(pmc, code, &pc, pc_len);
+ break;
}
}
diff --git a/pmc_common.c b/pmc_common.c
index d92b0cd..7e471dd 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -203,6 +203,9 @@ static int pmc_tlv_datalen(struct pmc *pmc, int id)
case TLV_PORT_DATA_SET_NP:
len += sizeof(struct port_ds_np);
break;
+ case TLV_PORT_COUNTERS:
+ len += sizeof(struct port_counters);
+ break;
case TLV_LOG_ANNOUNCE_INTERVAL:
case TLV_ANNOUNCE_RECEIPT_TIMEOUT:
case TLV_LOG_SYNC_INTERVAL:
diff --git a/port.c b/port.c
index 34837cc..83b0414 100644
--- a/port.c
+++ b/port.c
@@ -99,6 +99,7 @@ struct port {
enum port_state (*state_machine)(enum port_state state,
enum fsm_event event, int mdiff);
/* portDS */
+ struct port_counters pc;
struct PortIdentity portIdentity;
enum port_state state; /*portState*/
Integer64 asymmetry;
@@ -136,6 +137,8 @@ struct port {
static int port_capable(struct port *p);
static int port_is_ieee8021as(struct port *p);
static void port_nrate_initialize(struct port *p);
+static void counters_tx_increment(struct port *p, struct ptp_message *m);
+
static int announce_compare(struct ptp_message *m1, struct ptp_message *m2)
{
@@ -543,6 +546,9 @@ static int peer_prepare_and_send(struct port *p, struct ptp_message *msg,
if (cnt <= 0) {
return -1;
}
+
+ counters_tx_increment(p, msg);
+
if (msg_sots_valid(msg)) {
ts_add(&msg->hwts.ts, p->tx_timestamp_offset);
}
@@ -703,6 +709,7 @@ static int port_management_fill_response(struct port *target,
struct port_properties_np *ppn;
struct clock_description *desc;
struct mgmt_clock_description *cd;
+ struct port_counters *pc;
uint8_t *buf;
uint16_t u16;
@@ -857,6 +864,13 @@ static int port_management_fill_response(struct port *target,
datalen = sizeof(*ppn) + ppn->interface.length;
respond = 1;
break;
+ case TLV_PORT_COUNTERS:
+ pc = (struct port_counters *)tlv->data;
+ memcpy(pc, &target->pc, sizeof *pc);
+ ptp_text_set(&pc->interface, target->name);
+ datalen = sizeof(*pc) + pc->interface.length;
+ respond = 1;
+ break;
}
if (respond) {
if (datalen % 2) {
@@ -905,6 +919,11 @@ static int port_management_set(struct port *target,
target->neighborPropDelayThresh = pdsnp->neighborPropDelayThresh;
respond = 1;
break;
+ case TLV_PORT_COUNTERS:
+ /* clear counters*/
+ memcpy(&target->pc, tlv->data, sizeof(target->pc));
+ respond = 1;
+ break;
}
if (respond && !port_management_get_response(target, ingress, id, req))
pr_err("port %hu: failed to send management set response", portnum(target));
@@ -2324,37 +2343,47 @@ enum fsm_event port_event(struct port *p, int fd_index)
switch (msg_type(msg)) {
case SYNC:
process_sync(p, msg);
+ p->pc.sync_rx_cnt++;
break;
case DELAY_REQ:
if (process_delay_req(p, msg))
event = EV_FAULT_DETECTED;
+ p->pc.delay_req_rx_cnt++;
break;
case PDELAY_REQ:
if (process_pdelay_req(p, msg))
event = EV_FAULT_DETECTED;
+ p->pc.pdelay_req_rx_cnt++;
break;
case PDELAY_RESP:
if (process_pdelay_resp(p, msg))
event = EV_FAULT_DETECTED;
+ p->pc.pdelay_resp_rx_cnt++;
break;
case FOLLOW_UP:
process_follow_up(p, msg);
+ p->pc.follow_up_rx_cnt++;
break;
case DELAY_RESP:
process_delay_resp(p, msg);
+ p->pc.delay_resp_rx_cnt++;
break;
case PDELAY_RESP_FOLLOW_UP:
process_pdelay_resp_fup(p, msg);
+ p->pc.pdelay_resp_fup_rx_cnt++;
break;
case ANNOUNCE:
if (process_announce(p, msg))
event = EV_STATE_DECISION_EVENT;
+ p->pc.annonce_rx_cnt++;
break;
case SIGNALING:
+ p->pc.signaling_rx_cnt++;
break;
case MANAGEMENT:
if (clock_manage(p->clock, p, msg))
event = EV_STATE_DECISION_EVENT;
+ p->pc.mgmtd_rx_cnt++;
break;
}
@@ -2390,6 +2419,9 @@ int port_prepare_and_send(struct port *p, struct ptp_message *msg, int event)
if (cnt <= 0) {
return -1;
}
+
+ counters_tx_increment(p, msg);
+
if (msg_sots_valid(msg)) {
ts_add(&msg->hwts.ts, p->tx_timestamp_offset);
}
@@ -2576,6 +2608,9 @@ void port_notify_event(struct port *p, enum notification event)
msg_len = msg->header.messageLength;
if (msg_pre_send(msg))
goto err;
+
+ counters_tx_increment(p, msg);
+
clock_send_notification(p->clock, msg, msg_len, event);
err:
msg_put(msg);
@@ -2689,3 +2724,39 @@ enum port_state port_state(struct port *port)
{
return port->state;
}
+
+static void counters_tx_increment(struct port *p, struct ptp_message *m)
+{
+ switch (msg_type(m)) {
+ case SYNC:
+ p->pc.sync_tx_cnt++;
+ break;
+ case DELAY_REQ:
+ p->pc.delay_req_tx_cnt++;
+ break;
+ case PDELAY_REQ:
+ p->pc.pdelay_req_tx_cnt++;
+ break;
+ case PDELAY_RESP:
+ p->pc.pdelay_resp_tx_cnt++;
+ break;
+ case FOLLOW_UP:
+ p->pc.follow_up_tx_cnt++;
+ break;
+ case DELAY_RESP:
+ p->pc.delay_resp_tx_cnt++;
+ break;
+ case PDELAY_RESP_FOLLOW_UP:
+ p->pc.pdelay_resp_fup_tx_cnt++;
+ break;
+ case ANNOUNCE:
+ p->pc.annonce_tx_cnt++;
+ break;
+ case SIGNALING:
+ p->pc.signaling_tx_cnt++;
+ break;
+ case MANAGEMENT:
+ p->pc.mgmtd_tx_cnt++;
+ break;
+ }
+}
diff --git a/tlv.c b/tlv.c
index cef10a0..f061d33 100644
--- a/tlv.c
+++ b/tlv.c
@@ -65,6 +65,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
struct subscribe_events_np *sen;
struct port_properties_np *ppn;
struct mgmt_clock_description *cd;
+ struct port_counters *pc;
int extra_len = 0, len;
uint8_t *buf;
uint16_t u16;
@@ -258,6 +259,13 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
extra_len = sizeof(struct port_properties_np);
extra_len += ppn->interface.length;
break;
+ case TLV_PORT_COUNTERS:
+ if (data_len < sizeof(struct port_counters))
+ goto bad_length;
+ pc = (struct port_counters *) m->data;
+ extra_len = sizeof(struct port_counters);
+ extra_len += pc->interface.length;
+ break;
case TLV_SAVE_IN_NON_VOLATILE_STORAGE:
case TLV_RESET_NON_VOLATILE_STORAGE:
case TLV_INITIALIZE:
diff --git a/tlv.h b/tlv.h
index c345afe..fa55a0d 100644
--- a/tlv.h
+++ b/tlv.h
@@ -101,6 +101,7 @@ enum management_action {
#define TLV_LOG_MIN_PDELAY_REQ_INTERVAL 0x6001
#define TLV_PORT_DATA_SET_NP 0xC002
#define TLV_PORT_PROPERTIES_NP 0xC004
+#define TLV_PORT_COUNTERS 0xC008
/* Management error ID values */
#define TLV_RESPONSE_TOO_BIG 0x0001
@@ -213,6 +214,30 @@ struct port_properties_np {
struct PTPText interface;
} PACKED;
+struct port_counters {
+ uint64_t sync_rx_cnt;
+ uint64_t delay_req_rx_cnt;
+ uint64_t pdelay_req_rx_cnt;
+ uint64_t pdelay_resp_rx_cnt;
+ uint64_t follow_up_rx_cnt;
+ uint64_t delay_resp_rx_cnt;
+ uint64_t pdelay_resp_fup_rx_cnt;
+ uint64_t annonce_rx_cnt;
+ uint64_t signaling_rx_cnt;
+ uint64_t mgmtd_rx_cnt;
+ uint64_t sync_tx_cnt;
+ uint64_t delay_req_tx_cnt;
+ uint64_t pdelay_req_tx_cnt;
+ uint64_t pdelay_resp_tx_cnt;
+ uint64_t follow_up_tx_cnt;
+ uint64_t delay_resp_tx_cnt;
+ uint64_t pdelay_resp_fup_tx_cnt;
+ uint64_t annonce_tx_cnt;
+ uint64_t signaling_tx_cnt;
+ uint64_t mgmtd_tx_cnt;
+ struct PTPText interface;
+} PACKED;
+
#define PROFILE_ID_LEN 6
struct mgmt_clock_description {
- support set(clear) counters of port RX/TX messages
Signed-off-by: Mykola Zhuravel <***@mellanox.com>
---
clock.c | 1 +
pmc.c | 45 ++++++++++++++++++++++++++++++++++++++
pmc_common.c | 3 +++
port.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tlv.c | 8 +++++++
tlv.h | 25 +++++++++++++++++++++
6 files changed, 153 insertions(+)
diff --git a/clock.c b/clock.c
index da15882..8c8ca9a 100644
--- a/clock.c
+++ b/clock.c
@@ -1303,6 +1303,7 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
switch (mgt->id) {
case TLV_PORT_PROPERTIES_NP:
+ case TLV_PORT_COUNTERS:
if (p != c->uds_port) {
/* Only the UDS port allowed. */
clock_management_send_error(p, msg, TLV_NOT_SUPPORTED);
diff --git a/pmc.c b/pmc.c
index a991880..3067f16 100644
--- a/pmc.c
+++ b/pmc.c
@@ -108,6 +108,7 @@ struct management_id idtab[] = {
{ "LOG_MIN_PDELAY_REQ_INTERVAL", TLV_LOG_MIN_PDELAY_REQ_INTERVAL, do_get_action },
{ "PORT_DATA_SET_NP", TLV_PORT_DATA_SET_NP, do_set_action },
{ "PORT_PROPERTIES_NP", TLV_PORT_PROPERTIES_NP, do_get_action },
+ { "PORT_COUNTERS", TLV_PORT_COUNTERS, do_set_action},
};
static const char *action_string[] = {
@@ -198,6 +199,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
struct portDS *p;
struct port_ds_np *pnp;
struct port_properties_np *ppnp;
+ struct port_counters *pc;
if (msg_type(msg) != MANAGEMENT) {
return;
}
@@ -492,6 +494,39 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
pid2str(&ppnp->portIdentity), ps_str[ppnp->port_state],
ts_str[ppnp->timestamping], text2str(&ppnp->interface));
break;
+ case TLV_PORT_COUNTERS:
+ pc = (struct port_counters *) mgt->data;
+ fprintf(fp, "TLV_PORT_COUNTERS "
+ IFMT "interface %s"
+ IFMT "sync_rx_cnt %" PRIu64
+ IFMT "delay_req_rx_cnt %" PRIu64
+ IFMT "pdelay_req_rx_cnt %" PRIu64
+ IFMT "pdelay_resp_rx_cnt %" PRIu64
+ IFMT "follow_up_rx_cnt %" PRIu64
+ IFMT "delay_resp_rx_cnt %" PRIu64
+ IFMT "pdelay_resp_fup_rx_cnt %" PRIu64
+ IFMT "annonce_rx_cnt %" PRIu64
+ IFMT "signaling_rx_cnt %" PRIu64
+ IFMT "mgmtd_rx_cnt %" PRIu64
+ IFMT "sync_tx_cnt %" PRIu64
+ IFMT "delay_req_tx_cnt %" PRIu64
+ IFMT "pdelay_req_tx_cnt %" PRIu64
+ IFMT "pdelay_resp_tx_cnt %" PRIu64
+ IFMT "follow_up_tx_cnt %" PRIu64
+ IFMT "delay_resp_tx_cnt %" PRIu64
+ IFMT "pdelay_resp_fup_tx_cnt %" PRIu64
+ IFMT "annonce_tx_cnt %" PRIu64
+ IFMT "signaling_tx_cnt %" PRIu64
+ IFMT "mgmtd_tx_cnt %" PRIu64,
+ text2str(&pc->interface),
+ pc->sync_rx_cnt, pc->delay_req_rx_cnt, pc->pdelay_req_rx_cnt,
+ pc->pdelay_resp_rx_cnt, pc->follow_up_rx_cnt, pc->delay_resp_rx_cnt,
+ pc->pdelay_resp_fup_rx_cnt, pc->annonce_rx_cnt, pc->signaling_rx_cnt,
+ pc->mgmtd_rx_cnt, pc->sync_tx_cnt, pc->delay_req_tx_cnt, pc->pdelay_req_tx_cnt,
+ pc->pdelay_resp_tx_cnt, pc->follow_up_tx_cnt, pc->delay_resp_tx_cnt,
+ pc->pdelay_resp_fup_tx_cnt, pc->annonce_tx_cnt, pc->signaling_tx_cnt,
+ pc->mgmtd_tx_cnt);
+ break;
}
out:
fprintf(fp, "\n");
@@ -514,6 +549,8 @@ static void do_set_action(int action, int index, char *str)
int cnt, code = idtab[index].code;
int leap_61, leap_59, utc_off_valid;
int ptp_timescale, time_traceable, freq_traceable;
+ int pc_len;
+ struct port_counters pc;
switch (action) {
case GET:
@@ -597,6 +634,14 @@ static void do_set_action(int action, int index, char *str)
}
pmc_send_set_action(pmc, code, &pnp, sizeof(pnp));
break;
+ case TLV_PORT_COUNTERS:
+ pc_len = sizeof(pc);
+ memset(&pc, 0, pc_len);
+ if (pc_len % 2) {
+ pc_len++;
+ }
+ pmc_send_set_action(pmc, code, &pc, pc_len);
+ break;
}
}
diff --git a/pmc_common.c b/pmc_common.c
index d92b0cd..7e471dd 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -203,6 +203,9 @@ static int pmc_tlv_datalen(struct pmc *pmc, int id)
case TLV_PORT_DATA_SET_NP:
len += sizeof(struct port_ds_np);
break;
+ case TLV_PORT_COUNTERS:
+ len += sizeof(struct port_counters);
+ break;
case TLV_LOG_ANNOUNCE_INTERVAL:
case TLV_ANNOUNCE_RECEIPT_TIMEOUT:
case TLV_LOG_SYNC_INTERVAL:
diff --git a/port.c b/port.c
index 34837cc..83b0414 100644
--- a/port.c
+++ b/port.c
@@ -99,6 +99,7 @@ struct port {
enum port_state (*state_machine)(enum port_state state,
enum fsm_event event, int mdiff);
/* portDS */
+ struct port_counters pc;
struct PortIdentity portIdentity;
enum port_state state; /*portState*/
Integer64 asymmetry;
@@ -136,6 +137,8 @@ struct port {
static int port_capable(struct port *p);
static int port_is_ieee8021as(struct port *p);
static void port_nrate_initialize(struct port *p);
+static void counters_tx_increment(struct port *p, struct ptp_message *m);
+
static int announce_compare(struct ptp_message *m1, struct ptp_message *m2)
{
@@ -543,6 +546,9 @@ static int peer_prepare_and_send(struct port *p, struct ptp_message *msg,
if (cnt <= 0) {
return -1;
}
+
+ counters_tx_increment(p, msg);
+
if (msg_sots_valid(msg)) {
ts_add(&msg->hwts.ts, p->tx_timestamp_offset);
}
@@ -703,6 +709,7 @@ static int port_management_fill_response(struct port *target,
struct port_properties_np *ppn;
struct clock_description *desc;
struct mgmt_clock_description *cd;
+ struct port_counters *pc;
uint8_t *buf;
uint16_t u16;
@@ -857,6 +864,13 @@ static int port_management_fill_response(struct port *target,
datalen = sizeof(*ppn) + ppn->interface.length;
respond = 1;
break;
+ case TLV_PORT_COUNTERS:
+ pc = (struct port_counters *)tlv->data;
+ memcpy(pc, &target->pc, sizeof *pc);
+ ptp_text_set(&pc->interface, target->name);
+ datalen = sizeof(*pc) + pc->interface.length;
+ respond = 1;
+ break;
}
if (respond) {
if (datalen % 2) {
@@ -905,6 +919,11 @@ static int port_management_set(struct port *target,
target->neighborPropDelayThresh = pdsnp->neighborPropDelayThresh;
respond = 1;
break;
+ case TLV_PORT_COUNTERS:
+ /* clear counters*/
+ memcpy(&target->pc, tlv->data, sizeof(target->pc));
+ respond = 1;
+ break;
}
if (respond && !port_management_get_response(target, ingress, id, req))
pr_err("port %hu: failed to send management set response", portnum(target));
@@ -2324,37 +2343,47 @@ enum fsm_event port_event(struct port *p, int fd_index)
switch (msg_type(msg)) {
case SYNC:
process_sync(p, msg);
+ p->pc.sync_rx_cnt++;
break;
case DELAY_REQ:
if (process_delay_req(p, msg))
event = EV_FAULT_DETECTED;
+ p->pc.delay_req_rx_cnt++;
break;
case PDELAY_REQ:
if (process_pdelay_req(p, msg))
event = EV_FAULT_DETECTED;
+ p->pc.pdelay_req_rx_cnt++;
break;
case PDELAY_RESP:
if (process_pdelay_resp(p, msg))
event = EV_FAULT_DETECTED;
+ p->pc.pdelay_resp_rx_cnt++;
break;
case FOLLOW_UP:
process_follow_up(p, msg);
+ p->pc.follow_up_rx_cnt++;
break;
case DELAY_RESP:
process_delay_resp(p, msg);
+ p->pc.delay_resp_rx_cnt++;
break;
case PDELAY_RESP_FOLLOW_UP:
process_pdelay_resp_fup(p, msg);
+ p->pc.pdelay_resp_fup_rx_cnt++;
break;
case ANNOUNCE:
if (process_announce(p, msg))
event = EV_STATE_DECISION_EVENT;
+ p->pc.annonce_rx_cnt++;
break;
case SIGNALING:
+ p->pc.signaling_rx_cnt++;
break;
case MANAGEMENT:
if (clock_manage(p->clock, p, msg))
event = EV_STATE_DECISION_EVENT;
+ p->pc.mgmtd_rx_cnt++;
break;
}
@@ -2390,6 +2419,9 @@ int port_prepare_and_send(struct port *p, struct ptp_message *msg, int event)
if (cnt <= 0) {
return -1;
}
+
+ counters_tx_increment(p, msg);
+
if (msg_sots_valid(msg)) {
ts_add(&msg->hwts.ts, p->tx_timestamp_offset);
}
@@ -2576,6 +2608,9 @@ void port_notify_event(struct port *p, enum notification event)
msg_len = msg->header.messageLength;
if (msg_pre_send(msg))
goto err;
+
+ counters_tx_increment(p, msg);
+
clock_send_notification(p->clock, msg, msg_len, event);
err:
msg_put(msg);
@@ -2689,3 +2724,39 @@ enum port_state port_state(struct port *port)
{
return port->state;
}
+
+static void counters_tx_increment(struct port *p, struct ptp_message *m)
+{
+ switch (msg_type(m)) {
+ case SYNC:
+ p->pc.sync_tx_cnt++;
+ break;
+ case DELAY_REQ:
+ p->pc.delay_req_tx_cnt++;
+ break;
+ case PDELAY_REQ:
+ p->pc.pdelay_req_tx_cnt++;
+ break;
+ case PDELAY_RESP:
+ p->pc.pdelay_resp_tx_cnt++;
+ break;
+ case FOLLOW_UP:
+ p->pc.follow_up_tx_cnt++;
+ break;
+ case DELAY_RESP:
+ p->pc.delay_resp_tx_cnt++;
+ break;
+ case PDELAY_RESP_FOLLOW_UP:
+ p->pc.pdelay_resp_fup_tx_cnt++;
+ break;
+ case ANNOUNCE:
+ p->pc.annonce_tx_cnt++;
+ break;
+ case SIGNALING:
+ p->pc.signaling_tx_cnt++;
+ break;
+ case MANAGEMENT:
+ p->pc.mgmtd_tx_cnt++;
+ break;
+ }
+}
diff --git a/tlv.c b/tlv.c
index cef10a0..f061d33 100644
--- a/tlv.c
+++ b/tlv.c
@@ -65,6 +65,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
struct subscribe_events_np *sen;
struct port_properties_np *ppn;
struct mgmt_clock_description *cd;
+ struct port_counters *pc;
int extra_len = 0, len;
uint8_t *buf;
uint16_t u16;
@@ -258,6 +259,13 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
extra_len = sizeof(struct port_properties_np);
extra_len += ppn->interface.length;
break;
+ case TLV_PORT_COUNTERS:
+ if (data_len < sizeof(struct port_counters))
+ goto bad_length;
+ pc = (struct port_counters *) m->data;
+ extra_len = sizeof(struct port_counters);
+ extra_len += pc->interface.length;
+ break;
case TLV_SAVE_IN_NON_VOLATILE_STORAGE:
case TLV_RESET_NON_VOLATILE_STORAGE:
case TLV_INITIALIZE:
diff --git a/tlv.h b/tlv.h
index c345afe..fa55a0d 100644
--- a/tlv.h
+++ b/tlv.h
@@ -101,6 +101,7 @@ enum management_action {
#define TLV_LOG_MIN_PDELAY_REQ_INTERVAL 0x6001
#define TLV_PORT_DATA_SET_NP 0xC002
#define TLV_PORT_PROPERTIES_NP 0xC004
+#define TLV_PORT_COUNTERS 0xC008
/* Management error ID values */
#define TLV_RESPONSE_TOO_BIG 0x0001
@@ -213,6 +214,30 @@ struct port_properties_np {
struct PTPText interface;
} PACKED;
+struct port_counters {
+ uint64_t sync_rx_cnt;
+ uint64_t delay_req_rx_cnt;
+ uint64_t pdelay_req_rx_cnt;
+ uint64_t pdelay_resp_rx_cnt;
+ uint64_t follow_up_rx_cnt;
+ uint64_t delay_resp_rx_cnt;
+ uint64_t pdelay_resp_fup_rx_cnt;
+ uint64_t annonce_rx_cnt;
+ uint64_t signaling_rx_cnt;
+ uint64_t mgmtd_rx_cnt;
+ uint64_t sync_tx_cnt;
+ uint64_t delay_req_tx_cnt;
+ uint64_t pdelay_req_tx_cnt;
+ uint64_t pdelay_resp_tx_cnt;
+ uint64_t follow_up_tx_cnt;
+ uint64_t delay_resp_tx_cnt;
+ uint64_t pdelay_resp_fup_tx_cnt;
+ uint64_t annonce_tx_cnt;
+ uint64_t signaling_tx_cnt;
+ uint64_t mgmtd_tx_cnt;
+ struct PTPText interface;
+} PACKED;
+
#define PROFILE_ID_LEN 6
struct mgmt_clock_description {
--
2.8.4
2.8.4