Commit 22c7e74f authored by Aurelio Colosimo's avatar Aurelio Colosimo

arch-spec: socket api rewritten to use wrpc-sw functions

This patch is to substitute the obsolete spec-socket.c implementation by
calling the functions provided by wrpc-sw api (called ptpd_netif.h).
Signed-off-by: Aurelio Colosimo's avatarAurelio Colosimo <aurelio@aureliocolosimo.it>
parent 7287742e
......@@ -37,6 +37,7 @@ specdev-objects := $(WRPCSW_ROOT)/dev/uart.o \
$(WRPCSW_ROOT)/dev/minic.o \
$(WRPCSW_ROOT)/arch/lm32/irq.o \
$(WRPCSW_ROOT)/dev/sdb.o \
$(WRPCSW_ROOT)/lib/net.o \
$(PTPNOPOSIX_ROOT)/softpll/softpll_ng.o \
$(LIBARCH): $(OBJ-libarch)
......
......@@ -9,127 +9,56 @@
#include <ppsi/diag.h>
#include <pps_gen.h>
#include <softpll_ng.h>
#include <ptpd_netif.h>
int spec_errno;
Octet buffer_out[PP_PACKET_SIZE + 14]; // 14 is ppi->proto_ofst for ethernet mode
struct spec_socket_data_t
{
uint32_t phase_transition;
uint32_t dmtd_phase;
};
static struct spec_socket_data_t spec_socket_data;
/* This function should init the minic and get the mac address */
int spec_open_ch(struct pp_instance *ppi)
{
#ifdef PPSI_SLAVE
uint8_t fake_addr[] = {0x00, 0x10, 0x20, 0x30, 0x40, 0x50};
#else
uint8_t fake_addr[] = {0x99, 0x99, 0x99, 0x99, 0x99, 0x99};
#endif
struct spec_socket_data_t *s;
s = (struct spec_socket_data_t *)NP(ppi)->ch[PP_NP_EVT].arch_data;
hexp_port_state_t pstate;
ep_init(fake_addr);
ep_enable(1, 1);
minic_init();
shw_pps_gen_init();
memcpy(NP(ppi)->ch[PP_NP_GEN].addr, fake_addr, 6);
memcpy(NP(ppi)->ch[PP_NP_EVT].addr, fake_addr, 6);
NP(ppi)->ch[PP_NP_EVT].arch_data = &spec_socket_data;
if (halexp_get_port_state(&pstate, OPTS(ppi)->iface_name) < 0)
return -1;
s->phase_transition = pstate.t2_phase_transition;
s->dmtd_phase = pstate.phase_val;
return 0;
}
static inline int inside_range(int min, int max, int x)
{
if(min < max)
return (x>=min && x<=max);
else
return (x<=max || x>=min);
}
static void spec_linearize_rx_timestamp(TimeInternal *ts, int32_t dmtd_phase,
int cntr_ahead, int transition_point, int clock_period)
{
int trip_lo, trip_hi;
int phase;
// "phase" transition: DMTD output value (in picoseconds)
// at which the transition of rising edge
// TS counter will appear
ts->raw_phase = dmtd_phase;
phase = clock_period -1 -dmtd_phase;
wr_socket_t *sock;
mac_addr_t mac;
wr_sockaddr_t addr;
// calculate the range within which falling edge timestamp is stable
// (no possible transitions)
trip_lo = transition_point - clock_period / 4;
if(trip_lo < 0) trip_lo += clock_period;
addr.family = PTPD_SOCK_RAW_ETHERNET;
addr.ethertype = ETH_P_1588;
memcpy(addr.mac, PP_MCAST_MACADDRESS, sizeof(mac_addr_t));
trip_hi = transition_point + clock_period / 4;
if(trip_hi >= clock_period) trip_hi -= clock_period;
if (inside_range(trip_lo, trip_hi, phase)) {
// We are within +- 25% range of transition area of
// rising counter. Take the falling edge counter value as the
// "reliable" one. cntr_ahead will be 1 when the rising edge
//counter is 1 tick ahead of the falling edge counter
ts->nanoseconds -= cntr_ahead ? (clock_period / 1000) : 0;
sock = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &addr);
if (!sock)
return -1;
// check if the phase is before the counter transition value
// and eventually increase the counter by 1 to simulate a
// timestamp transition exactly at s->phase_transition
//DMTD phase value
if(inside_range(trip_lo, transition_point, phase))
ts->nanoseconds += clock_period / 1000;
ptpd_netif_get_hw_addr(sock, &mac);
memcpy(NP(ppi)->ch[PP_NP_EVT].addr, &mac, sizeof(mac_addr_t));
NP(ppi)->ch[PP_NP_EVT].custom = sock;
}
ts->phase = phase - transition_point - 1;
if(ts->phase < 0) ts->phase += clock_period;
ts->phase = clock_period - 1 - ts->phase;
return 0;
}
/* To receive and send packets, we call the minic low-level stuff */
int spec_recv_packet(struct pp_instance *ppi, void *pkt, int len,
TimeInternal *t)
{
static int led;
struct hw_timestamp hwts;
int got;
struct spec_socket_data_t *s;
s = (struct spec_socket_data_t *)NP(ppi)->ch[PP_NP_EVT].arch_data;
wr_socket_t *sock;
wr_timestamp_t wr_ts;
wr_sockaddr_t addr;
sock = (wr_socket_t *)NP(ppi)->ch[PP_NP_EVT].custom;
got = ptpd_netif_recvfrom(sock, &addr, pkt, len, &wr_ts);
led ^= 1; /* blink one led at each rx event */
gpio_out(GPIO_PIN_LED_LINK, led);
got = minic_rx_frame(pkt, pkt+ETH_HEADER_SIZE, len, &hwts);
/* FIXME check mac of received packet? */
if (t) {
t->seconds = hwts.sec;
t->nanoseconds = hwts.nsec;
t->phase = 0;
t->correct = hwts.valid;
t->raw_nsec = hwts.nsec;
t->raw_ahead = hwts.ahead;
spll_read_ptracker(0, &t->raw_phase, NULL);
spec_linearize_rx_timestamp(t, t->raw_phase, hwts.ahead,
s->phase_transition, REF_CLOCK_PERIOD_PS);
t->seconds = wr_ts.sec;
t->nanoseconds = wr_ts.nsec;
t->phase = wr_ts.phase;
t->correct = wr_ts.correct;
t->raw_nsec = wr_ts.raw_nsec;
t->raw_ahead = wr_ts.raw_ahead;
t->raw_phase = wr_ts.raw_phase;
}
return got;
}
......@@ -137,34 +66,30 @@ int spec_recv_packet(struct pp_instance *ppi, void *pkt, int len,
int spec_send_packet(struct pp_instance *ppi, void *pkt, int len,
TimeInternal *t, int chtype, int use_pdelay_addr)
{
static int led;
struct spec_ethhdr hdr;
struct hw_timestamp hwts;
int got;
if (OPTS(ppi)->gptp_mode)
memcpy(hdr.h_dest, PP_PEER_MACADDRESS, ETH_ALEN);
else
memcpy(hdr.h_dest, PP_MCAST_MACADDRESS, ETH_ALEN);
int snt;
wr_socket_t *sock;
wr_timestamp_t wr_ts;
wr_sockaddr_t addr;
sock = (wr_socket_t *)NP(ppi)->ch[PP_NP_EVT].custom;
memcpy(hdr.h_source, NP(ppi)->ch[PP_NP_GEN].addr, ETH_ALEN);
hdr.h_proto = ETH_P_1588;
addr.ethertype = ETH_P_1588;
memcpy(&addr.mac, PP_MCAST_MACADDRESS, sizeof(mac_addr_t));
led ^= 1; /* blink the other led at each tx event */
gpio_out(GPIO_PIN_LED_STATUS, led);
got = minic_tx_frame((uint8_t*)&hdr, pkt, len+ETH_HEADER_SIZE, &hwts);
pp_timed_printf("before ptpd_netif_sendto %d\n", len);
snt = ptpd_netif_sendto(sock, &addr, pkt, len, &wr_ts);
pp_timed_printf("after ptpd_netif_sendto %d\n", len);
if (t) {
t->seconds = hwts.sec;
t->nanoseconds = hwts.nsec;
t->seconds = wr_ts.sec;
t->nanoseconds = wr_ts.nsec;
t->phase = 0;
t->correct = hwts.valid;
t->correct = wr_ts.correct;
PP_VPRINTF("%s: got=%d, sec=%d, nsec=%d\n", __FUNCTION__, got,
PP_VPRINTF("%s: snt=%d, sec=%d, nsec=%d\n", __FUNCTION__, snt,
t->seconds, t->nanoseconds);
}
return got;
return snt;
}
int spec_net_init(struct pp_instance *ppi)
......
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