Commit b9768a6b authored by Alessandro Rubini's avatar Alessandro Rubini

wrpc: initial support for UDP (to be verified -- DO NOT MERGE)

This works in my host simulation, and is not tested yet on real hw.

As it is now, it won't build if CONFIG_IP is not set in wrpc-sw, so
it can't be merged until this is fixed.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 7b41dc83
......@@ -86,6 +86,10 @@ enum pp_timeouts {
#define PP_GEN_PORT 320
#define PP_DEFAULT_DOMAIN_ADDRESS "224.0.1.129"
#define PP_PDELAY_DOMAIN_ADDRESS "224.0.0.107"
#define PP_DEFAULT_DOMAIN_BIN "\xe0\x00\x01\x81"
#define PP_PDELAY_DOMAIN_BIN "\xe0\x00\x00\x6b"
#define PP_DEFAULT_DOMAIN_MAC "\x01\x00\x5e\x00\x01\x81"
#define PP_PDELAY_DOMAIN_MAC "\x01\x00\x5e\x00\x00\x6b"
/* Raw ethernet dependent */
#ifndef ETH_P_1588
......
......@@ -6,44 +6,93 @@
*/
#include <ppsi/ppsi.h>
#include "ptpdump.h"
#include <ptpd_netif.h> /* wrpc-sw */
#include <shell.h> /* wrpc-sw */
#include "../lib/ipv4.h" /* dot-dot from wrpc-sw/include */
#include "../wrc_ptp.h" /* dot-dot from wrpc-sw/include */
extern struct pp_instance ppi_static; /* not static already (wrpc-sw uses it) */
static int cmd_proto(const char *args[])
{
static char *protos[] = {"raw", "udp"};
int prev = ppi_static.proto;
int proto = prev;
if (args[0]) {
if (*args[0] == '0' || *args[0] == 'r')
proto = PPSI_PROTO_RAW;
if (*args[0] == '1' || *args[0] == 'u')
proto = PPSI_PROTO_UDP;
}
pp_printf("PTP protocol: %s\n", protos[proto]);
if (proto != prev) {
ppi_static.proto = proto;
wrc_ptp_stop();
wrc_ptp_start();
}
return 0;
}
DEFINE_WRC_COMMAND(proto) = {
.name = "proto",
.exec = cmd_proto,
};
/*
* we know we create one socket only in wrpc. The buffer size used to be
* 512. Let's keep it unchanged, because we might enqueue a few frames.
* I think this can be decreased to 256, but I'd better play safe
* We create either one (raw) or two (udp) sockets. The buffer size used to be
* 512. Now that's two of them, let's reduce to 256. IT looks like we don't
* equeue more than sync and f.up (or pdelay-resp and its own f.up)
*/
static uint8_t __ptp_queue[512];
static uint8_t __ptp_queue[256];
static struct wrpc_socket __static_ptp_socket = {
.queue.buff = __ptp_queue,
.queue.size = sizeof(__ptp_queue),
};
static uint8_t __ptp_queu2[256];
static struct wrpc_socket __static_ptp_socke2 = {
.queue.buff = __ptp_queu2,
.queue.size = sizeof(__ptp_queu2),
};
static struct wr_udp_addr ptp_udp_addr;
/* This function should init the minic and get the mac address */
static int wrpc_open_ch(struct pp_instance *ppi)
{
struct wrpc_socket *sock;
struct wrpc_socket *sock, *soc2;
mac_addr_t mac;
struct wr_sockaddr addr;
char *macaddr = PP_MCAST_MACADDRESS;
if (ppi->mech == PP_P2P_MECH)
macaddr = PP_PDELAY_MACADDRESS;
addr.ethertype = htons(ETH_P_1588);
memcpy(addr.mac, macaddr, sizeof(mac_addr_t));
sock = ptpd_netif_create_socket(&__static_ptp_socket, &addr,
PTPD_SOCK_RAW_ETHERNET, 0);
if (!sock)
if (ppi_static.proto == PPSI_PROTO_RAW) {
addr.ethertype = htons(ETH_P_1588);
memcpy(addr.mac, macaddr, sizeof(mac_addr_t));
sock = ptpd_netif_create_socket(&__static_ptp_socket, &addr,
PTPD_SOCK_RAW_ETHERNET, 0);
soc2 = sock;
} else {
sock = ptpd_netif_create_socket(&__static_ptp_socket, NULL,
PTPD_SOCK_UDP, PP_EVT_PORT);
soc2 = ptpd_netif_create_socket(&__static_ptp_socke2, NULL,
PTPD_SOCK_UDP, PP_GEN_PORT);
}
if (!sock || !soc2)
return -1;
ptpd_netif_get_hw_addr(sock, &mac);
memcpy(ppi->ch[PP_NP_EVT].addr, &mac, sizeof(mac_addr_t));
ppi->ch[PP_NP_EVT].custom = sock;
memcpy(ppi->ch[PP_NP_GEN].addr, &mac, sizeof(mac_addr_t));
ppi->ch[PP_NP_GEN].custom = sock;
ppi->ch[PP_NP_GEN].custom = soc2;
/* for udp, fill the address too */
memcpy(&ptp_udp_addr.saddr, "\x0a\x0b\x0c\x0d", 4);
memcpy(&ptp_udp_addr.daddr, PP_DEFAULT_DOMAIN_BIN, 4);
return 0;
}
......@@ -55,8 +104,16 @@ static int wrpc_net_recv(struct pp_instance *ppi, void *pkt, int len,
struct wrpc_socket *sock;
struct wr_timestamp wr_ts;
struct wr_sockaddr addr;
sock = ppi->ch[PP_NP_EVT].custom;
got = ptpd_netif_recvfrom(sock, &addr, pkt, len, &wr_ts);
if (got <= 0) {
/* try the other socket too -- it's the same for raw proto */
sock = ppi->ch[PP_NP_GEN].custom;
got = ptpd_netif_recvfrom(sock, &addr, pkt, len, &wr_ts);
}
if (got <= 0)
return got;
if (t) {
t->seconds = wr_ts.sec;
......@@ -73,7 +130,7 @@ static int wrpc_net_recv(struct pp_instance *ppi, void *pkt, int len,
/* wrpc-sw may pass this in USER_CFLAGS, to remove footprint */
#ifndef CONFIG_NO_PTPDUMP
/* The header is separate, so dump payload only */
if (got > 0 && pp_diag_allow(ppi, frames, 2))
if (pp_diag_allow(ppi, frames, 2))
dump_payloadpkt("recv: ", pkt, got, t);
#endif
......@@ -84,20 +141,34 @@ static int wrpc_net_send(struct pp_instance *ppi, void *pkt, int len,
int msgtype)
{
int snt;
int proto = ppi_static.proto;
int chtype = pp_msgtype_info[msgtype].chtype;
struct wrpc_socket *sock;
struct wr_timestamp wr_ts;
struct wr_sockaddr addr;
TimeInternal *t = &ppi->last_snt_time;
int is_pdelay = pp_msgtype_info[msgtype].is_pdelay;
static const uint8_t macaddr[2][ETH_ALEN] = {
static const uint8_t macaddr_raw[2][ETH_ALEN] = {
[PP_E2E_MECH] = PP_MCAST_MACADDRESS,
[PP_P2P_MECH] = PP_PDELAY_MACADDRESS,
};
uint16_t ethertype[] = {ETH_P_1588, 0x0800 /* IPV4 */};
char *macaddr_udp[] = {PP_MCAST_MACADDRESS, PP_DEFAULT_DOMAIN_MAC};
static uint16_t udpport[] = {
[PP_NP_GEN] = PP_GEN_PORT,
[PP_NP_EVT] = PP_EVT_PORT,
};
sock = ppi->ch[PP_NP_EVT].custom;
sock = ppi->ch[chtype].custom;
addr.ethertype = htons(ETH_P_1588);
memcpy(&addr.mac, macaddr[is_pdelay], sizeof(mac_addr_t));
addr.ethertype = htons(ethertype[proto]);
memcpy(&addr.mac, macaddr_raw[proto], sizeof(mac_addr_t));
if (proto == PPSI_PROTO_UDP) {
ptp_udp_addr.sport = htons(udpport[chtype]);
ptp_udp_addr.dport = htons(udpport[chtype]);
fill_udp(pkt, len, &ptp_udp_addr);
}
snt = ptpd_netif_sendto(sock, &addr, pkt, len, &wr_ts);
......@@ -123,6 +194,8 @@ static int wrpc_net_send(struct pp_instance *ppi, void *pkt, int len,
static int wrpc_net_exit(struct pp_instance *ppi)
{
ptpd_netif_close_socket(ppi->ch[PP_NP_EVT].custom);
ptpd_netif_close_socket(ppi->ch[PP_NP_GEN].custom);
ppi->ch[PP_NP_GEN].custom = ppi->ch[PP_NP_EVT].custom = NULL;
return 0;
}
......
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