Commit 63ac3c7b authored by Wesley W. Terpstra's avatar Wesley W. Terpstra

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
......@@ -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();
}
}
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