- support getting counters of port RX/TX messages
- support set(clear) counters of port RX/TX messages

Signed-off-by: Mykola Zhuravel <myk...@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


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to