Skip to content
Snippets Groups Projects
Commit 63ac3c7b authored by Wesley W. Terpstra's avatar Wesley W. Terpstra
Browse files

BOOTP implemented

wrc_main starts bootp whenever link goes up
Rever Arria2 sys clock to 125MHz -- we had packet loss at 62.5MHz
Added IP training support to the shell
Have the shell reset the packet filter when the MAC is changed
parent 4e384293
Branches
Tags
No related merge requests found
......@@ -6,7 +6,7 @@
/* Board-specific parameters */
/* WR Core system/CPU clock frequency in Hz */
#define CPU_CLOCK 62500000ULL
#define CPU_CLOCK 125000000ULL
/* WR Reference clock period (picoseconds) and frequency (Hz) */
#define REF_CLOCK_PERIOD_PS 8000
......@@ -19,7 +19,7 @@
#define NET_MAX_SOCKETS 3
/* Socket buffer size, determines the max. RX packet size */
#define NET_SKBUF_SIZE 256
#define NET_SKBUF_SIZE 512
/* Number of auxillary clock channels - usually equal to the number of FMCs */
#define NUM_AUX_CLOCKS 1
......
......@@ -72,6 +72,8 @@ void arp_poll(void) {
wr_sockaddr_t addr;
int len;
if (needIP) return; /* can't do ARP w/o an address... */
if ((len = ptpd_netif_recvfrom(arp_socket, &addr, buf, sizeof(buf), 0)) > 0)
if ((len = process_arp(buf, len)) > 0)
ptpd_netif_sendto(arp_socket, &addr, buf, len, 0);
......
#include <string.h>
#include "ipv4.h"
#define IP_VERSION 0
#define IP_TOS (IP_VERSION+1)
#define IP_LEN (IP_TOS+1)
#define IP_ID (IP_LEN+2)
#define IP_FLAGS (IP_ID+2)
#define IP_TTL (IP_FLAGS+2)
#define IP_PROTOCOL (IP_TTL+1)
#define IP_CHECKSUM (IP_PROTOCOL+1)
#define IP_SOURCE (IP_CHECKSUM+2)
#define IP_DEST (IP_SOURCE+4)
#define IP_END (IP_DEST+4)
#define UDP_VIRT_SADDR (IP_END-12)
#define UDP_VIRT_DADDR (UDP_VIRT_SADDR+4)
#define UDP_VIRT_ZEROS (UDP_VIRT_DADDR+4)
#define UDP_VIRT_PROTO (UDP_VIRT_ZEROS+1)
#define UDP_VIRT_LENGTH (UDP_VIRT_PROTO+1)
#define UDP_SPORT (IP_END)
#define UDP_DPORT (UDP_SPORT+2)
#define UDP_LENGTH (UDP_DPORT+2)
#define UDP_CHECKSUM (UDP_LENGTH+2)
#define UDP_END (UDP_CHECKSUM+2)
#define BOOTP_OP (UDP_END)
#define BOOTP_HTYPE (BOOTP_OP+1)
#define BOOTP_HLEN (BOOTP_HTYPE+1)
#define BOOTP_HOPS (BOOTP_HLEN+1)
#define BOOTP_XID (BOOTP_HOPS+1)
#define BOOTP_SECS (BOOTP_XID+4)
#define BOOTP_UNUSED (BOOTP_SECS+2)
#define BOOTP_CIADDR (BOOTP_UNUSED+2)
#define BOOTP_YIADDR (BOOTP_CIADDR+4)
#define BOOTP_SIADDR (BOOTP_YIADDR+4)
#define BOOTP_GIADDR (BOOTP_SIADDR+4)
#define BOOTP_CHADDR (BOOTP_GIADDR+4)
#define BOOTP_SNAME (BOOTP_CHADDR+16)
#define BOOTP_FILE (BOOTP_SNAME+64)
#define BOOTP_VEND (BOOTP_FILE+128)
#define BOOTP_END (BOOTP_VEND+64)
int send_bootp(uint8_t* buf, int retry) {
unsigned short sum;
// ----------- BOOTP ------------
buf[BOOTP_OP] = 1; /* bootrequest */
buf[BOOTP_HTYPE] = 1; /* ethernet */
buf[BOOTP_HLEN] = 6; /* MAC length */
buf[BOOTP_HOPS] = 0;
/* A unique identifier for the request !!! FIXME */
get_mac_addr(buf+BOOTP_XID);
buf[BOOTP_XID+0] ^= buf[BOOTP_XID+4];
buf[BOOTP_XID+1] ^= buf[BOOTP_XID+5];
buf[BOOTP_XID+2] ^= (retry >> 8) & 0xFF;
buf[BOOTP_XID+3] ^= retry & 0xFF;
buf[BOOTP_SECS] = (retry >> 8) & 0xFF;
buf[BOOTP_SECS+1] = retry & 0xFF;
memset(buf+BOOTP_UNUSED, 0, 2);
memset(buf+BOOTP_CIADDR, 0, 4); /* own IP if known */
memset(buf+BOOTP_YIADDR, 0, 4);
memset(buf+BOOTP_SIADDR, 0, 4);
memset(buf+BOOTP_GIADDR, 0, 4);
memset(buf+BOOTP_CHADDR, 0, 16);
get_mac_addr(buf+BOOTP_CHADDR); /* own MAC address */
memset(buf+BOOTP_SNAME, 0, 64); /* desired BOOTP server */
memset(buf+BOOTP_FILE, 0, 128); /* desired BOOTP file */
memset(buf+BOOTP_VEND, 0, 64); /* vendor extensions */
// ------------ UDP -------------
memset(buf+UDP_VIRT_SADDR, 0, 4);
memset(buf+UDP_VIRT_DADDR, 0xFF, 4);
buf[UDP_VIRT_ZEROS] = 0;
buf[UDP_VIRT_PROTO] = 0x11; /* UDP */
buf[UDP_VIRT_LENGTH] = (BOOTP_END-IP_END) >> 8;
buf[UDP_VIRT_LENGTH+1] = (BOOTP_END-IP_END) & 0xff;
buf[UDP_SPORT] = 0;
buf[UDP_SPORT+1] = 68; /* BOOTP client */
buf[UDP_DPORT] = 0;
buf[UDP_DPORT+1] = 67; /* BOOTP server */
buf[UDP_LENGTH] = (BOOTP_END-IP_END) >> 8;
buf[UDP_LENGTH+1] = (BOOTP_END-IP_END) & 0xff;
buf[UDP_CHECKSUM] = 0;
buf[UDP_CHECKSUM+1] = 0;
sum = ipv4_checksum((unsigned short*)(buf+UDP_VIRT_SADDR), (BOOTP_END-UDP_VIRT_SADDR)/2);
if (sum == 0) sum = 0xFFFF;
buf[UDP_CHECKSUM+0] = (sum >> 8);
buf[UDP_CHECKSUM+1] = sum & 0xff;
// ------------ IP --------------
buf[IP_VERSION] = 0x45;
buf[IP_TOS] = 0;
buf[IP_LEN+0] = (BOOTP_END) >> 8;
buf[IP_LEN+1] = (BOOTP_END) & 0xff;
buf[IP_ID+0] = 0;
buf[IP_ID+1] = 0;
buf[IP_FLAGS+0] = 0;
buf[IP_FLAGS+1] = 0;
buf[IP_TTL] = 63;
buf[IP_PROTOCOL] = 17; /* UDP */
buf[IP_CHECKSUM+0] = 0;
buf[IP_CHECKSUM+1] = 0;
memset(buf+IP_SOURCE, 0, 4);
memset(buf+IP_DEST, 0xFF, 4);
sum = ipv4_checksum((unsigned short*)(buf+IP_VERSION), (IP_END-IP_VERSION)/2);
buf[IP_CHECKSUM+0] = sum >> 8;
buf[IP_CHECKSUM+1] = sum & 0xff;
mprintf("Sending BOOTP request...\n");
return BOOTP_END;
}
int process_bootp(uint8_t* buf, int len)
{
uint8_t mac[6];
get_mac_addr(mac);
mprintf("recvd: %d %x %d %d %d\n", len, buf[IP_VERSION], buf[IP_PROTOCOL], buf[UDP_DPORT+1], buf[UDP_SPORT+1]);
if (len != BOOTP_END) return 0;
if (buf[IP_VERSION] != 0x45) return 0;
if (buf[IP_PROTOCOL] != 17 ||
buf[UDP_DPORT] != 0 || buf[UDP_DPORT+1] != 68 ||
buf[UDP_SPORT] != 0 || buf[UDP_SPORT+1] != 67) return 0;
if (memcmp(buf+BOOTP_CHADDR, mac, 6)) return 0;
mprintf("Discovered IP address!\n");
memcpy(myIP, buf+BOOTP_YIADDR, 4);
return 1;
}
......@@ -3,8 +3,6 @@
#include "ipv4.h"
#include "ptpd_netif.h"
static wr_socket_t* icmp_socket;
#define IP_VERSION 0
#define IP_TOS (IP_VERSION+1)
#define IP_LEN (IP_TOS+1)
......@@ -22,20 +20,7 @@ static wr_socket_t* icmp_socket;
#define ICMP_CHECKSUM (ICMP_CODE+1)
#define ICMP_END (ICMP_CHECKSUM+2)
void icmp_init(const char* if_name) {
wr_sockaddr_t saddr;
/* Configure socket filter */
memset(&saddr, 0, sizeof(saddr));
strcpy(saddr.if_name, if_name);
get_mac_addr(&saddr.mac); /* Unicast */
saddr.ethertype = htons(0x0800); /* IPv4 */
saddr.family = PTPD_SOCK_RAW_ETHERNET;
icmp_socket = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &saddr);
}
static int process_icmp(uint8_t* buf, int len) {
int process_icmp(uint8_t* buf, int len) {
int iplen, hisBodyLen;
uint8_t hisIP[4];
uint16_t sum;
......@@ -89,13 +74,3 @@ static int process_icmp(uint8_t* buf, int len) {
return 24+hisBodyLen;
}
void icmp_poll(void) {
uint8_t buf[ICMP_END+136];
wr_sockaddr_t addr;
int len;
if ((len = ptpd_netif_recvfrom(icmp_socket, &addr, buf, sizeof(buf), 0)) > 0)
if ((len = process_icmp(buf, len)) > 0)
ptpd_netif_sendto(icmp_socket, &addr, buf, len, 0);
}
......@@ -2,8 +2,11 @@
#include "endpoint.h"
#include "ipv4.h"
#include "ptpd_netif.h"
uint8_t myIP[4];
int needIP = 1;
static wr_socket_t* ipv4_socket;
unsigned int ipv4_checksum(unsigned short* buf, int shorts) {
int i;
......@@ -19,19 +22,45 @@ unsigned int ipv4_checksum(unsigned short* buf, int shorts) {
return (~sum & 0xffff);
}
void ipv4_init(const char* if_name, uint32_t ip) {
uint32_t ip_bigendian;
void ipv4_init(const char* if_name) {
wr_sockaddr_t saddr;
ip_bigendian = htonl(ip);
memcpy(myIP, &ip_bigendian, 4);
/* Configure socket filter */
memset(&saddr, 0, sizeof(saddr));
strcpy(saddr.if_name, if_name);
get_mac_addr(&saddr.mac[0]); /* Unicast */
saddr.ethertype = htons(0x0800); /* IPv4 */
saddr.family = PTPD_SOCK_RAW_ETHERNET;
arp_init(if_name);
icmp_init(if_name);
// TRACE_DEV("My IP: %d.%d.%d.%d\n", myIP[0], myIP[1], myIP[2], myIP[3]);
ipv4_socket = ptpd_netif_create_socket(PTPD_SOCK_RAW_ETHERNET, 0, &saddr);
}
void ipv4_poll(void) {
arp_poll();
icmp_poll();
static int retry = 0;
static int timer = 0;
uint8_t buf[400];
wr_sockaddr_t addr;
int len;
if ((len = ptpd_netif_recvfrom(ipv4_socket, &addr, buf, sizeof(buf), 0)) > 0) {
if (needIP && process_bootp(buf, len-14)) {
retry = 0;
needIP = 0;
timer = 0;
}
if (!needIP && (len = process_icmp(buf, len-14)) > 0)
ptpd_netif_sendto(ipv4_socket, &addr, buf, len, 0);
}
if (needIP && timer == 0) {
len = send_bootp(buf, ++retry);
memset(addr.mac, 0xFF, 6);
addr.ethertype = htons(0x0800); /* IPv4 */
ptpd_netif_sendto(ipv4_socket, &addr, buf, len, 0);
}
if (needIP && ++timer == 100000) timer = 0;
}
#ifndef IPV4_H
#define IPV4_H
void ipv4_init(const char* if_name, uint32_t ip);
void ipv4_init(const char* if_name);
void ipv4_poll(void);
/* Internal to IP stack: */
unsigned int ipv4_checksum(unsigned short* buf, int shorts);
void arp_init(const char* if_name);
void icmp_init(const char* if_name);
void arp_poll(void);
void icmp_poll(void);
extern uint8_t myMAC[6];
extern uint8_t myIP[4];
extern int needIP;
int process_icmp(uint8_t* buf, int len);
int process_bootp(uint8_t* buf, int len); /* non-zero if IP was set */
int send_bootp(uint8_t* buf, int retry);
#endif
......@@ -3,6 +3,6 @@ OBJS_LIB= lib/mprintf.o \
ifneq ($(WITH_ETHERBONE), 0)
OBJS_LIB += lib/arp.o lib/icmp.o lib/ipv4.o
OBJS_LIB += lib/arp.o lib/icmp.o lib/ipv4.o lib/bootp.o
endif
\ No newline at end of file
......@@ -27,10 +27,15 @@ int cmd_ip(const char *args[])
} else if (!strcasecmp(args[0], "set") && args[1]) {
decode_ip(args[1], ip);
memcpy(myIP, ip, 4);
needIP = !ip[0] && !ip[1] && !ip[2] && !ip[3];
} else {
return -EINVAL;
}
mprintf("IP-address: %d.%d.%d.%d\n",
ip[0], ip[1], ip[2], ip[3]);
if (needIP) {
mprintf("IP-address: in training\n");
} else {
mprintf("IP-address: %d.%d.%d.%d\n",
ip[0], ip[1], ip[2], ip[3]);
}
}
......@@ -31,6 +31,7 @@ int cmd_mac(const char *args[])
} else if (!strcasecmp(args[0], "set") && args[1]) {
decode_mac(args[1], mac);
set_mac_addr(mac);
pfilter_init_default();
} else if (!strcasecmp(args[0], "setp") && args[1]) {
decode_mac(args[1], mac);
set_persistent_mac(mac);
......
......@@ -14,6 +14,7 @@
//#include "eeprom.h"
#include "softpll_ng.h"
#include "persistent_mac.h"
#include "lib/ipv4.h"
#include "wrc_ptp.h"
......@@ -59,9 +60,8 @@ void wrc_initialize()
pps_gen_init();
wrc_ptp_init();
/* Derive the IP from the MAC address (10.x.y.z) */
/* This will be done with BOOTP in the near future */
ipv4_init("wru1", 0x0A000000 | mac_addr[3] << 16 | mac_addr[4] << 8 | mac_addr[5]);
ipv4_init("wru1");
arp_init("wru1");
}
#define LINK_WENT_UP 1
......@@ -136,33 +136,34 @@ int main(void)
wrc_gui_mode = 0;
wrc_initialize();
shell_init();
wrc_ptp_set_mode(WRC_MODE_SLAVE);
wrc_ptp_start();
for(;;)
{
shell_init();
wrc_ptp_set_mode(WRC_MODE_SLAVE);
wrc_ptp_start();
for (;;)
{
int l_status = wrc_check_link();
switch (l_status)
{
case LINK_WENT_UP:
needIP = 1;
break;
case LINK_UP:
update_rx_queues();
ipv4_poll();
arp_poll();
break;
case LINK_WENT_DOWN:
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
break;
}
}
ui_update();
wrc_ptp_update();
ui_update();
wrc_ptp_update();
spll_update_aux_clocks();
ipv4_poll();
}
}
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