From 39f3a83dcd333a507c26c6bd2054dd9c1c53177e Mon Sep 17 00:00:00 2001 From: Adam Wujek <adam.wujek@cern.ch> Date: Fri, 9 Jan 2015 16:20:12 +0100 Subject: [PATCH] userspace/tools: make wr_phytool to use ports info via shm Signed-off-by: Adam Wujek <adam.wujek@cern.ch> --- userspace/libwr/include/libwr/ptpd_netif.h | 10 ++- userspace/libwr/ptpd_netif.c | 45 ++++++++------ userspace/tools/wr_phytool.c | 71 +++++++++++++++------- 3 files changed, 82 insertions(+), 44 deletions(-) diff --git a/userspace/libwr/include/libwr/ptpd_netif.h b/userspace/libwr/include/libwr/ptpd_netif.h index e3da1b0f0..14618fe42 100644 --- a/userspace/libwr/include/libwr/ptpd_netif.h +++ b/userspace/libwr/include/libwr/ptpd_netif.h @@ -5,6 +5,8 @@ #include <stdio.h> #include <net/ethernet.h> +#include <libwr/hal_shmem.h> +#include <libwr/hal_client.h> #define PTPD_SOCK_RAW_ETHERNET 1 #define PTPD_SOCK_UDP 2 @@ -80,7 +82,8 @@ int ptpd_netif_init(); // Creates UDP or Ethernet RAW socket (determined by sock_type) bound to bind_addr. If PTPD_FLAG_MULTICAST is set, the socket is // automatically added to multicast group. User can specify physical_port field to bind the socket to specific switch port only. struct wr_socket *ptpd_netif_create_socket(int sock_type, int flags, - struct wr_sockaddr *bind_addr); + struct wr_sockaddr *bind_addr, + struct hal_port_state *port); // Sends a UDP/RAW packet (data, data_length) to address provided in wr_sockaddr // For raw frames, mac/ethertype needs to be provided, for UDP - ip/port. @@ -94,7 +97,8 @@ int ptpd_netif_sendto(struct wr_socket *sock, struct wr_sockaddr *to, void *data // by data_length parameter. Sender information is stored in structure specified in 'from'. All RXed packets are timestamped and the timestamp // is stored in rx_timestamp (unless it's NULL). int ptpd_netif_recvfrom(struct wr_socket *sock, struct wr_sockaddr *from, void *data, - size_t data_length, struct wr_tstamp *rx_timestamp); + size_t data_length, struct wr_tstamp *rx_timestamp, + struct hal_port_state *port); // Closes the socket. int ptpd_netif_close_socket(struct wr_socket *sock); @@ -112,7 +116,7 @@ int ptpd_netif_poll(struct wr_sockaddr *); /* Timebase adjustment functions - the servo should not call the HAL directly */ int ptpd_netif_adjust_counters(int64_t adjust_sec, int32_t adjust_nsec); -int ptpd_netif_get_dmtd_phase(struct wr_socket *sock, int32_t *phase); +int ptpd_netif_get_dmtd_phase(int32_t *phase, struct hal_port_state *p); void ptpd_netif_linearize_rx_timestamp(struct wr_tstamp *ts, int32_t dmtd_phase, int cntr_ahead, int transition_point, int clock_period); diff --git a/userspace/libwr/ptpd_netif.c b/userspace/libwr/ptpd_netif.c index ea50a2f25..d28727725 100644 --- a/userspace/libwr/ptpd_netif.c +++ b/userspace/libwr/ptpd_netif.c @@ -23,7 +23,10 @@ #include <asm/socket.h> #include <libwr/ptpd_netif.h> +#include <libwr/shmem.h> +#include <libwr/hal_shmem.h> #include <libwr/hal_client.h> +#include <libwr/switch_hw.h> #include <net/ethernet.h> #ifdef NETIF_VERBOSE @@ -83,27 +86,29 @@ static inline int inside_range(int min, int max, int x) } /* For debugging/testing purposes */ -int ptpd_netif_get_dmtd_phase(struct wr_socket *s, int32_t *phase) +int ptpd_netif_get_dmtd_phase(int32_t *phase, struct hal_port_state *p) { - hexp_port_state_t pstate; + int phase_val_valid_local; - halexp_get_port_state(&pstate, s->bind_addr.if_name); + if (!p) + return -1; + phase_val_valid_local = p->phase_val_valid; if (phase) - *phase = pstate.phase_val; - return pstate.phase_val_valid; + *phase = phase_val_valid_local; + return phase_val_valid_local; } -static void update_dmtd(struct wr_socket *s) +static void update_dmtd(struct wr_socket *s, struct hal_port_state *p) { - hexp_port_state_t pstate; - if (tmo_expired(&s->dmtd_update_tmo)) { - halexp_get_port_state(&pstate, s->bind_addr.if_name); + if (!p) + return; + if (tmo_expired(&s->dmtd_update_tmo)) { // FIXME: ccheck if phase value is ready - s->dmtd_phase = pstate.phase_val; - s->dmtd_phase_valid = pstate.phase_val_valid; + s->dmtd_phase = p->phase_val; + s->dmtd_phase_valid = p->phase_val_valid; tmo_restart(&s->dmtd_update_tmo); } @@ -169,14 +174,13 @@ int ptpd_netif_init() } struct wr_socket *ptpd_netif_create_socket(int sock_type, int flags, - struct wr_sockaddr *bind_addr) + struct wr_sockaddr *bind_addr, + struct hal_port_state *port) { struct wr_socket *s; struct sockaddr_ll sll; struct ifreq f; - hexp_port_state_t pstate; - int fd; // fprintf(stderr,"CreateSocket!\n"); @@ -184,7 +188,7 @@ struct wr_socket *ptpd_netif_create_socket(int sock_type, int flags, if (sock_type != PTPD_SOCK_RAW_ETHERNET) return NULL; - if (halexp_get_port_state(&pstate, bind_addr->if_name) < 0) + if (!port) return NULL; fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); @@ -267,10 +271,10 @@ struct wr_socket *ptpd_netif_create_socket(int sock_type, int flags, s->fd = fd; // store the linearization parameters - s->clock_period = pstate.clock_period; - s->phase_transition = pstate.t2_phase_transition; + s->clock_period = REF_CLOCK_PERIOD_PS; + s->phase_transition = DEFAULT_T2_PHASE_TRANS; s->dmtd_phase_valid = 0; - s->dmtd_phase = pstate.phase_val; + s->dmtd_phase = port->phase_val; tmo_init(&s->dmtd_update_tmo, DMTD_UPDATE_INTERVAL); @@ -406,7 +410,8 @@ static void poll_tx_timestamp(struct wr_socket *s, struct wr_tstamp *tx_timestam } int ptpd_netif_recvfrom(struct wr_socket *s, struct wr_sockaddr *from, void *data, - size_t data_length, struct wr_tstamp *rx_timestamp) + size_t data_length, struct wr_tstamp *rx_timestamp, + struct hal_port_state *port) { struct etherpacket pkt; struct msghdr msg; @@ -468,7 +473,7 @@ int ptpd_netif_recvfrom(struct wr_socket *s, struct wr_sockaddr *from, void *dat rx_timestamp->raw_nsec = sts->hwtimeraw.tv_nsec; rx_timestamp->raw_ahead = cntr_ahead; - update_dmtd(s); + update_dmtd(s, port); if (s->dmtd_phase_valid) { ptpd_netif_linearize_rx_timestamp(rx_timestamp, s->dmtd_phase, diff --git a/userspace/tools/wr_phytool.c b/userspace/tools/wr_phytool.c index ab46cbc3c..7349dcb27 100644 --- a/userspace/tools/wr_phytool.c +++ b/userspace/tools/wr_phytool.c @@ -50,27 +50,46 @@ static struct EP_WB _ep_wb; extern int rts_connect(); -int get_nports_from_hal(void) +static int hal_nports_local; +static struct wrs_shm_head *hal_head; +static struct hal_port_state *hal_ports; + +int hal_shm_init(void) { + int ii; struct hal_shmem_header *h; - struct wrs_shm_head *hal_head; - int hal_nports_local; /* local copy of number of ports */ - hal_head = wrs_shm_get(wrs_shm_hal, "", WRS_SHM_READ); + /* open shmem to HAL */ + hal_head = wrs_shm_get(wrs_shm_hal, "", WRS_SHM_READ | WRS_SHM_LOCKED); if (!hal_head) { - fprintf(stderr, "unable to open shm for HAL!\n"); - exit(-1); + fprintf(stderr, + "FATAL: wr_phytool unable to open shm to HAL.\n"); + return -1; } + h = (void *)hal_head + hal_head->data_off; - /* Assume number of ports does not change in runtime */ - hal_nports_local = h->nports; + + while (1) { /* wait forever for HAL to produce consistent nports */ + ii = wrs_shm_seqbegin(hal_head); + /* Assume number of ports does not change in runtime */ + hal_nports_local = h->nports; + if (!wrs_shm_seqretry(hal_head, ii)) + break; + fprintf(stderr, "INFO: wr_phytool Wait for HAL.\n"); + sleep(1); + } + + /* Even after HAL restart, HAL will place structures at the same + * addresses. No need to re-dereference pointer at each read. */ + hal_ports = wrs_shm_follow(hal_head, h->ports); if (hal_nports_local > HAL_MAX_PORTS) { - fprintf(stderr, "Too many ports reported by HAL. " + fprintf(stderr, + "FATAL: wr_phytool Too many ports reported by HAL." "%d vs %d supported\n", hal_nports_local, HAL_MAX_PORTS); - exit(-1); + return -1; } - return hal_nports_local; + return 0; } int fpga_map(char *prgname) @@ -247,6 +266,7 @@ void calc_trans(int ep, int argc, char *argv[]) FILE *f_log = NULL; struct wr_sockaddr sock_addr, from; int bitslide,phase, i; + struct hal_port_state *port; signal (SIGINT, sighandler); for(i=0;i<MAX_BITSLIDES;i++) @@ -265,8 +285,12 @@ void calc_trans(int ep, int argc, char *argv[]) memset(sock_addr.mac, 0xff, 6); assert(ptpd_netif_init() == 0); + assert(hal_shm_init() == 0); + port = hal_lookup_port(hal_ports, hal_nports_local, + sock_addr.if_name); + sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &sock_addr, + port); - sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &sock_addr); // fpga_writel(EP_DMCR_N_AVG_W(1024) | EP_DMCR_EN, IDX_TO_EP(ep) + EP_REG(DMCR)); if( rts_connect() < 0) @@ -312,7 +336,8 @@ void calc_trans(int ep, int argc, char *argv[]) to.family = PTPD_SOCK_RAW_ETHERNET; // socket type ptpd_netif_sendto(sock, &to, buf, 64, &ts_tx); - int n = ptpd_netif_recvfrom(sock, &from, buf, 64, &ts_rx); + int n = ptpd_netif_recvfrom(sock, &from, buf, 64, &ts_rx, + port); if(n>0) @@ -378,6 +403,7 @@ void pps_adjustment_test(int ep, int argc, char *argv[]) struct wr_socket *sock; struct wr_sockaddr sock_addr, from; int adjust_count = 0; + struct hal_port_state *port; signal (SIGINT, sighandler); @@ -387,9 +413,11 @@ void pps_adjustment_test(int ep, int argc, char *argv[]) memset(sock_addr.mac, 0xff, 6); assert(ptpd_netif_init() == 0); - - sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &sock_addr); - + assert(hal_shm_init() == 0); + port = hal_lookup_port(hal_ports, hal_nports_local, + sock_addr.if_name); + sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &sock_addr, + port); while(!quit) { @@ -409,7 +437,8 @@ void pps_adjustment_test(int ep, int argc, char *argv[]) // if(!ptpd_netif_adjust_in_progress()) { ptpd_netif_sendto(sock, &to, buf, 64, &ts_tx); - ptpd_netif_recvfrom(sock, &from, buf, 64, &ts_rx); + ptpd_netif_recvfrom(sock, &from, buf, 64, &ts_rx, + port); printf("TX timestamp: correct %d %12lld:%12d\n", ts_tx.correct, ts_tx.sec, ts_tx.nsec); printf("RX timestamp: correct %d %12lld:%12d\n", ts_rx.correct, ts_rx.sec, ts_rx.nsec); adjust_count --; @@ -423,9 +452,8 @@ void rt_command(int ep, int argc, char *argv[]) { struct rts_pll_state pstate; int i; - int nports; - nports = get_nports_from_hal(); + assert(hal_shm_init() == 0); /* to get hal_nports_local */ if( rts_connect() < 0) { @@ -437,9 +465,10 @@ void rt_command(int ep, int argc, char *argv[]) if(!strcmp(argv[3], "show")) { - printf("RTS State Dump [%d physical ports]:\n", nports); + printf("RTS State Dump [%d physical ports]:\n", + hal_nports_local); printf("CurrentRef: %d Mode: %d Flags: %x\n", pstate.current_ref, pstate.mode, pstate.flags); - for (i = 0; i < nports; i++) + for (i = 0; i < hal_nports_local; i++) printf("wr%-2d: setpoint: %-8dps current: %-8dps loopback: %-8dps flags: %x\n", i, pstate.channels[i].phase_setpoint, pstate.channels[i].phase_current, -- GitLab