Commit 513151b2 authored by Alessandro Rubini's avatar Alessandro Rubini

arch-wrs: replace some RPC with shared memory access

The HAL process, in the white rabbit switch, is now exporting data
structures in shared memory. Thus, we don't need to "get_port_state"
by RPC, and accessing shared memory is enough.  This change in ppsi
involves the following changes:

arch-wrs/wrs-startup.c: offer global hal_ports[] for others to use
(yes, globals are bad, I know...)

arch-wrs/include/ppsi-wrs.h: provide pp_wrs_lookup_port

time-wrs/wrs-socket.c: use shmem. This means some values are now
hardwired as constants, because they were passed as such from the hal.

arch-wrs/main-loop.c: verify link up or down in the shared mem status

arch-wrs/wrs-calibration.c: wrs_read_calibration_data uses shmem
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent dbb08dae
......@@ -16,9 +16,23 @@
*/
#include <minipc.h>
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
extern struct minipc_ch *hal_ch;
extern struct minipc_ch *ppsi_ch;
extern struct hal_port_state *hal_ports;
extern int hal_nports;
static inline struct hal_port_state *pp_wrs_lookup_port(char *name)
{
int i;
for (i = 0; i < hal_nports; i++)
if (hal_ports[i].in_use &&!strcmp(name, hal_ports[i].name))
return hal_ports + i;
return NULL;
}
#define DEFAULT_TO 200000 /* ms */
......
......@@ -18,7 +18,6 @@
#include <ppsi-wrs.h>
#include <wr-api.h>
#include <hal_exports.h>
extern struct minipc_pd __rpcdef_get_port_state;
/* Call pp_state_machine for each instance. To be called periodically,
* when no packets are incoming */
......@@ -30,15 +29,14 @@ static int run_all_state_machines(struct pp_globals *ppg)
for (j = 0; j < ppg->nlinks; j++) {
struct pp_instance *ppi = INST(ppg, j);
int old_lu = WR_DSPOR(ppi)->linkUP;
hexp_port_state_t state;
struct hal_port_state *p;
minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_get_port_state,
&state, ppi->iface_name);
/* FIXME: we should save this pointer in the ppi itself */
p = pp_wrs_lookup_port(ppi->iface_name);
if ((state.valid) && (state.up))
WR_DSPOR(ppi)->linkUP = 1;
else
WR_DSPOR(ppi)->linkUP = 0;
WR_DSPOR(ppi)->linkUP =
(p->state != HAL_PORT_STATE_LINK_DOWN &&
p->state != HAL_PORT_STATE_DISABLED);
if (old_lu != WR_DSPOR(ppi)->linkUP) {
......
......@@ -6,42 +6,55 @@
*/
#include <ppsi/ppsi.h>
#include <math.h>
#define HAL_EXPORT_STRUCTURES
#include <ppsi-wrs.h>
#define HAL_EXPORT_STRUCTURES
#include <hal_exports.h>
int wrs_read_calibration_data(struct pp_instance *ppi,
uint32_t *delta_tx, uint32_t *delta_rx, int32_t *fix_alpha,
int32_t *clock_period)
{
hexp_port_state_t state;
minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_get_port_state,
&state, ppi->iface_name);
if(state.valid && state.tx_calibrated && state.rx_calibrated) {
pp_diag(ppi, servo, 1, "deltas: tx=%d, rx=%d\n",
state.delta_tx ,state.delta_rx);
if(delta_tx)
*delta_tx = state.delta_tx;
if(delta_rx)
*delta_rx = state.delta_rx;
if(fix_alpha)
*fix_alpha = state.fiber_fix_alpha;
if(clock_period)
*clock_period = state.clock_period;
return WR_HW_CALIB_OK;
}
return WR_HW_CALIB_NOT_FOUND;
struct hal_port_state *p;
/* The following fields come from struct hexp_port_state */
uint32_t port_delta_tx, port_delta_rx;
int32_t port_fix_alpha;
p = pp_wrs_lookup_port(ppi->iface_name);
if (!p)
return WR_HW_CALIB_NOT_FOUND;
if(!p->calib.tx_calibrated || !p->calib.rx_calibrated)
return WR_HW_CALIB_NOT_FOUND;
/*
* Like in wrs_net_init, we build fields that were in
* hexp_port_state from the "real" hal_port_state in the same
* way as the HAL itself was doing to fill the RPC structure.
* Formulas copied from libwr/hal_shmem.c (get_exported_state).
*/
port_delta_tx = p->calib.delta_tx_phy
+ p->calib.sfp.delta_tx + p->calib.delta_tx_board;
port_delta_rx = p->calib.delta_rx_phy
+ p->calib.sfp.delta_rx + p->calib.delta_rx_board;
port_fix_alpha = (double)pow(2.0, 40.0) *
((p->calib.sfp.alpha + 1.0) / (p->calib.sfp.alpha + 2.0)
- 0.5);
pp_diag(ppi, servo, 1, "deltas: tx=%d, rx=%d\n",
port_delta_tx, port_delta_rx);
if(delta_tx)
*delta_tx = port_delta_tx;
if(delta_rx)
*delta_rx = port_delta_rx;
if(fix_alpha)
*fix_alpha = port_fix_alpha;
if(clock_period)
*clock_period = 16000; /* REF_CLOCK_PERIOD_PS */
return WR_HW_CALIB_OK;
}
int wrs_calibrating_disable(struct pp_instance *ppi, int txrx)
......
......@@ -63,6 +63,8 @@ static struct pp_servo servo;
struct minipc_ch *hal_ch;
struct minipc_ch *ppsi_ch;
struct hal_port_state *hal_ports;
int hal_nports;
int main(int argc, char **argv)
{
......@@ -72,6 +74,8 @@ int main(int argc, char **argv)
unsigned long seed;
struct timex t;
int i, hal_retries;
struct wrs_shm_head *hal_head;
struct hal_shmem_header *h;
setbuf(stdout, NULL);
......@@ -95,6 +99,18 @@ int main(int argc, char **argv)
}
if (BUILT_WITH_WHITERABBIT) {
/* If we connected, we also know "for sure" shmem is there */
hal_head = wrs_shm_get(wrs_shm_hal,"", WRS_SHM_READ);
if (!hal_head) {
pp_printf("ppsi: Can't connect with HAL "
"shared memory\n");
exit(1);
}
h = (void *)hal_head + hal_head->data_off;
hal_nports = h->nports;
hal_ports = wrs_shm_follow(hal_head, h->ports);
/* And create your own channel, until we move to shmem too */
ppsi_ch = minipc_server_create("ptpd", 0);
if (!ppsi_ch) { /* FIXME should we retry ? */
pp_printf("ppsi: could not create minipc server");
......
......@@ -33,8 +33,6 @@
#include <hal_exports.h>
#include "../proto-ext-whiterabbit/wr-api.h"
extern struct minipc_pd __rpcdef_get_port_state;
#define ETHER_MTU 1518
#define DMTD_UPDATE_INTERVAL 500
#define PACKED __attribute__((packed))
......@@ -101,17 +99,17 @@ static inline int inside_range(int min, int max, int x)
return (x<=max || x>=min);
}
static void update_dmtd(struct wrs_socket *s, char *ifname)
static void update_dmtd(struct wrs_socket *s, struct pp_instance *ppi)
{
hexp_port_state_t pstate;
struct hal_port_state *p;
if (tmo_expired(&s->dmtd_update_tmo))
{
minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_get_port_state,
&pstate, ifname);
s->dmtd_phase = pstate.phase_val;
s->dmtd_phase_valid = pstate.phase_val_valid;
p = pp_wrs_lookup_port(ppi->iface_name);
if (!p)
return;
s->dmtd_phase = p->phase_val;
s->dmtd_phase_valid = p->phase_val_valid;
tmo_restart(&s->dmtd_update_tmo);
}
......@@ -219,7 +217,7 @@ static int wrs_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
t->raw_ahead = cntr_ahead;
update_dmtd(s, ppi->iface_name);
update_dmtd(s, ppi);
if (!WR_DSPOR(ppi)->wrModeOn) {
/* for non-wr-mode any reported stamp is correct */
t->correct = 1;
......@@ -453,7 +451,7 @@ static int wrs_net_exit(struct pp_instance *ppi);
static int wrs_net_init(struct pp_instance *ppi)
{
int r, i;
hexp_port_state_t pstate;
struct hal_port_state *p;
if (NP(ppi)->ch[PP_NP_GEN].arch_data)
wrs_net_exit(ppi);
......@@ -464,11 +462,10 @@ static int wrs_net_init(struct pp_instance *ppi)
if (r)
return r;
r = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_get_port_state,
&pstate, ppi->iface_name);
if (r)
return r;
/* We used to have a mini-rpc call, but we now access shmem */
p = pp_wrs_lookup_port(ppi->iface_name);
if (!p)
return -1;
/* Only one wrs_socket is created for each pp_instance, because
* wrs_socket is related to the interface and not to the pp_channel */
......@@ -477,10 +474,18 @@ static int wrs_net_init(struct pp_instance *ppi)
if (!s)
return -1;
s->clock_period = pstate.clock_period;
s->phase_transition = pstate.t2_phase_transition;
/*
* The following 3 values used to come from an RPC call. But
* the RPC structure is not the same as the one exported in
* shared memory (don't know why); so here I unroll the
* conversions, and what is constant in the HAL becomes
* constant here (ARub)
*/
s->clock_period = 16000; /* REF_CLOCK_PERIOD_PS */
s->phase_transition = 0; /* DEFAULT_T2_PHASE_TRANS */
s->dmtd_phase = p->phase_val;
s->dmtd_phase_valid = 0;
s->dmtd_phase = pstate.phase_val;
NP(ppi)->ch[PP_NP_GEN].arch_data = s;
NP(ppi)->ch[PP_NP_EVT].arch_data = s;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment