summaryrefslogtreecommitdiffstats
path: root/firmware/zpu
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/zpu')
-rw-r--r--firmware/zpu/apps/txrx_uhd.c150
-rw-r--r--firmware/zpu/lib/memory_map.h125
-rw-r--r--firmware/zpu/lib/net_common.c99
-rw-r--r--firmware/zpu/lib/net_common.h21
4 files changed, 162 insertions, 233 deletions
diff --git a/firmware/zpu/apps/txrx_uhd.c b/firmware/zpu/apps/txrx_uhd.c
index 68c24e872..12f173f5c 100644
--- a/firmware/zpu/apps/txrx_uhd.c
+++ b/firmware/zpu/apps/txrx_uhd.c
@@ -1,8 +1,5 @@
-//
-// Copyright 2010-2011 Ettus Research LLC
-//
/*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2010-2011 Ettus Research LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,94 +15,58 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <lwip/ip.h>
-#include <lwip/udp.h>
+//peripheral headers
#include "u2_init.h"
-#include "memory_map.h"
#include "spi.h"
+#include "i2c.h"
#include "hal_io.h"
#include "pic.h"
-#include <stdbool.h>
-#include "ethernet.h"
+
+//printf headers
#include "nonstdio.h"
-#include <net/padded_eth_hdr.h>
-#include <net_common.h>
-#include "memcpy_wa.h"
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include "clocks.h"
+
+//network headers
+#include "arp_cache.h"
+#include "ethernet.h"
+#include "net_common.h"
#include "usrp2/fw_common.h"
-#include <i2c.h>
-#include <ethertype.h>
-#include <arp_cache.h>
#include "udp_fw_update.h"
#include "pkt_ctrl.h"
-#include "banal.h"
-static void setup_network(void);
+//standard headers
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
-// ----------------------------------------------------------------
-// the fast-path setup global variables
-// ----------------------------------------------------------------
-static eth_mac_addr_t fp_mac_addr_src, fp_mac_addr_dst;
-struct socket_address fp_socket_src, fp_socket_dst;
extern uint16_t dsp0_dst_port, err0_dst_port, dsp1_dst_port;
-static void handle_udp_err0_packet(
+static void handle_udp_data_packet(
struct socket_address src, struct socket_address dst,
unsigned char *payload, int payload_len
){
- sr_udp_sm->err0_port = (((uint32_t)dst.port) << 16) | src.port;
- err0_dst_port = src.port;
- printf("Storing for async error path:\n");
- printf(" source udp port: %d\n", dst.port);
- printf(" destination udp port: %d\n", src.port);
- newline();
-}
+ size_t which;
+ switch(dst.port){
+ case USRP2_UDP_DSP0_PORT:
+ which = 0;
+ dsp0_dst_port = src.port;
+ break;
-static void handle_udp_dsp1_packet(
- struct socket_address src, struct socket_address dst,
- unsigned char *payload, int payload_len
-){
- sr_udp_sm->dsp1_port = (((uint32_t)dst.port) << 16) | src.port;
- dsp1_dst_port = src.port;
- printf("Storing for dsp1 path:\n");
- printf(" source udp port: %d\n", dst.port);
- printf(" destination udp port: %d\n", src.port);
- newline();
-}
+ case USRP2_UDP_DSP1_PORT:
+ which = 2;
+ dsp1_dst_port = src.port;
+ break;
-static void handle_udp_dsp0_packet(
- struct socket_address src, struct socket_address dst,
- unsigned char *payload, int payload_len
-){
- fp_mac_addr_src = *ethernet_mac_addr();
- arp_cache_lookup_mac(&src.addr, &fp_mac_addr_dst);
- fp_socket_src = dst;
- fp_socket_dst = src;
- sr_udp_sm->dsp0_port = (((uint32_t)dst.port) << 16) | src.port;
- dsp0_dst_port = src.port;
- printf("Storing for dsp0 path:\n");
- printf(" source mac addr: ");
- print_mac_addr(&fp_mac_addr_src); newline();
- printf(" source ip addr: ");
- print_ip_addr(&fp_socket_src.addr); newline();
- printf(" source udp port: %d\n", fp_socket_src.port);
- printf(" destination mac addr: ");
- print_mac_addr(&fp_mac_addr_dst); newline();
- printf(" destination ip addr: ");
- print_ip_addr(&fp_socket_dst.addr); newline();
- printf(" destination udp port: %d\n", fp_socket_dst.port);
- newline();
-
- //setup network
- setup_network();
+ case USRP2_UDP_ERR0_PORT:
+ which = 1;
+ err0_dst_port = src.port;
+ break;
+
+ default: return;
+ }
+ eth_mac_addr_t eth_mac_host; arp_cache_lookup_mac(&src.addr, &eth_mac_host);
+ setup_framer(eth_mac_host, *ethernet_mac_addr(), src, dst, which);
}
#define OTW_GPIO_BANK_TO_NUM(bank) \
@@ -278,6 +239,7 @@ static void handle_udp_ctrl_packet(
send_udp_pkt(USRP2_UDP_CTRL_PORT, src, &ctrl_data_out, sizeof(ctrl_data_out));
}
+#include <net/padded_eth_hdr.h>
static void handle_inp_packet(uint32_t *buff, size_t num_lines){
//test if its an ip recovery packet
@@ -318,40 +280,6 @@ void link_changed_callback(int speed){
}
}
-static void setup_network(void){
-
- //setup ethernet header machine
- sr_udp_sm->eth_hdr.mac_dst_0_1 = (fp_mac_addr_dst.addr[0] << 8) | fp_mac_addr_dst.addr[1];
- sr_udp_sm->eth_hdr.mac_dst_2_3 = (fp_mac_addr_dst.addr[2] << 8) | fp_mac_addr_dst.addr[3];
- sr_udp_sm->eth_hdr.mac_dst_4_5 = (fp_mac_addr_dst.addr[4] << 8) | fp_mac_addr_dst.addr[5];
- sr_udp_sm->eth_hdr.mac_src_0_1 = (fp_mac_addr_src.addr[0] << 8) | fp_mac_addr_src.addr[1];
- sr_udp_sm->eth_hdr.mac_src_2_3 = (fp_mac_addr_src.addr[2] << 8) | fp_mac_addr_src.addr[3];
- sr_udp_sm->eth_hdr.mac_src_4_5 = (fp_mac_addr_src.addr[4] << 8) | fp_mac_addr_src.addr[5];
- sr_udp_sm->eth_hdr.ether_type = ETHERTYPE_IPV4;
-
- //setup ip header machine
- unsigned int chksum = 0;
- sr_udp_sm->ip_hdr.ver_ihl_tos = CHKSUM(0x4500, &chksum); // IPV4, 5 words of header (20 bytes), TOS=0
- sr_udp_sm->ip_hdr.total_length = UDP_SM_INS_IP_LEN; // Don't checksum this line in SW
- sr_udp_sm->ip_hdr.identification = CHKSUM(0x0000, &chksum); // ID
- sr_udp_sm->ip_hdr.flags_frag_off = CHKSUM(0x4000, &chksum); // don't fragment
- sr_udp_sm->ip_hdr.ttl_proto = CHKSUM(0x2011, &chksum); // TTL=32, protocol = UDP (17 decimal)
- //sr_udp_sm->ip_hdr.checksum .... filled in below
- uint32_t src_ip_addr = fp_socket_src.addr.addr;
- uint32_t dst_ip_addr = fp_socket_dst.addr.addr;
- sr_udp_sm->ip_hdr.src_addr_high = CHKSUM(src_ip_addr >> 16, &chksum); // IP src high
- sr_udp_sm->ip_hdr.src_addr_low = CHKSUM(src_ip_addr & 0xffff, &chksum); // IP src low
- sr_udp_sm->ip_hdr.dst_addr_high = CHKSUM(dst_ip_addr >> 16, &chksum); // IP dst high
- sr_udp_sm->ip_hdr.dst_addr_low = CHKSUM(dst_ip_addr & 0xffff, &chksum); // IP dst low
- sr_udp_sm->ip_hdr.checksum = UDP_SM_INS_IP_HDR_CHKSUM | (chksum & 0xffff);
-
- //setup the udp header machine
- sr_udp_sm->udp_hdr.src_port = UDP_SM_INS_UDP_SRC_PORT;
- sr_udp_sm->udp_hdr.dst_port = UDP_SM_INS_UDP_DST_PORT;
- sr_udp_sm->udp_hdr.length = UDP_SM_INS_UDP_LEN;
- sr_udp_sm->udp_hdr.checksum = UDP_SM_LAST_WORD; // zero UDP checksum
-}
-
int
main(void)
{
@@ -370,9 +298,9 @@ main(void)
//2) register callbacks for udp ports we service
init_udp_listeners();
register_udp_listener(USRP2_UDP_CTRL_PORT, handle_udp_ctrl_packet);
- register_udp_listener(USRP2_UDP_DSP0_PORT, handle_udp_dsp0_packet);
- register_udp_listener(USRP2_UDP_ERR0_PORT, handle_udp_err0_packet);
- register_udp_listener(USRP2_UDP_DSP1_PORT, handle_udp_dsp1_packet);
+ register_udp_listener(USRP2_UDP_DSP0_PORT, handle_udp_data_packet);
+ register_udp_listener(USRP2_UDP_ERR0_PORT, handle_udp_data_packet);
+ register_udp_listener(USRP2_UDP_DSP1_PORT, handle_udp_data_packet);
#ifdef USRP2P
register_udp_listener(USRP2_UDP_UPDATE_PORT, handle_udp_fw_update_packet);
#endif
diff --git a/firmware/zpu/lib/memory_map.h b/firmware/zpu/lib/memory_map.h
index e08136053..132fdb6f6 100644
--- a/firmware/zpu/lib/memory_map.h
+++ b/firmware/zpu/lib/memory_map.h
@@ -187,22 +187,24 @@ typedef struct {
// 1KB of address space (== 256 32-bit write-only regs)
////////////////////////////////////////////////////
-#define SR_MISC 0
-#define SR_TX_PROT_ENG 32
-#define SR_RX_PROT_ENG 48
-#define SR_ROUTER_CTRL 64
-#define SR_UDP_SM 96
-#define SR_TX_DSP 208
-#define SR_TX_CTRL 224
-#define SR_RX_DSP0 160
-#define SR_RX_DSP1 240
-#define SR_RX_CTRL0 176
-#define SR_RX_CTRL1 32
-#define SR_TIME64 192
-#define SR_SIMTIMER 198
-#define SR_LAST 255
-
-#define _SR_ADDR(sr) (MISC_OUTPUT_BASE + (sr) * sizeof(uint32_t))
+#define SR_MISC 0 // 7 regs
+#define SR_SIMTIMER 8 // 2
+#define SR_TIME64 10 // 6
+#define SR_BUF_POOL 16 // 4
+
+#define SR_RX_FRONT 24 // 5
+#define SR_RX_CTRL0 32 // 9
+#define SR_RX_DSP0 48 // 7
+#define SR_RX_CTRL1 80 // 9
+#define SR_RX_DSP1 96 // 7
+
+#define SR_TX_FRONT 128 // ?
+#define SR_TX_CTRL 144 // 6
+#define SR_TX_DSP 160 // 5
+
+#define SR_UDP_SM 192 // 64
+
+#define _SR_ADDR(sr) (MISC_OUTPUT_BASE + (sr) * sizeof(uint32_t))
#define SR_ADDR_BLDRDONE _SR_ADDR(5)
@@ -215,20 +217,19 @@ typedef struct {
volatile uint32_t iface_ctrl;
} router_ctrl_t;
-#define router_ctrl ((router_ctrl_t *) _SR_ADDR(SR_ROUTER_CTRL))
+#define router_ctrl ((router_ctrl_t *) _SR_ADDR(SR_BUF_POOL))
// --- misc outputs ---
typedef struct {
- volatile uint32_t clk_ctrl;
- volatile uint32_t serdes_ctrl;
- volatile uint32_t adc_ctrl;
- volatile uint32_t leds;
- volatile uint32_t phy_ctrl; // LSB is reset line to eth phy
- volatile uint32_t debug_mux_ctrl;
- volatile uint32_t ram_page; // FIXME should go somewhere else...
- volatile uint32_t flush_icache; // Flush the icache
- volatile uint32_t led_src; // HW or SW control for LEDs
+ volatile uint32_t clk_ctrl;
+ volatile uint32_t serdes_ctrl;
+ volatile uint32_t adc_ctrl;
+ volatile uint32_t leds;
+ volatile uint32_t phy_ctrl; // LSB is reset line to eth phy
+ volatile uint32_t debug_mux_ctrl;
+ volatile uint32_t led_src; // HW or SW control for LEDs
+ volatile uint32_t flush_icache; // Flush the icache
} output_regs_t;
#define CLK_RESET (1<<4)
@@ -255,71 +256,15 @@ typedef struct {
#define output_regs ((output_regs_t *) MISC_OUTPUT_BASE)
-// --- udp tx regs ---
+// --- protocol framer regs ---
-typedef struct {
- // Bits 19:16 are control info; bits 15:0 are data (see below)
- // First two words are unused.
- volatile uint32_t _nope[2];
- //--- ethernet header - 14 bytes---
- volatile struct{
- uint32_t mac_dst_0_1; //word 2
- uint32_t mac_dst_2_3;
- uint32_t mac_dst_4_5;
- uint32_t mac_src_0_1;
- uint32_t mac_src_2_3;
- uint32_t mac_src_4_5;
- uint32_t ether_type; //word 8
- } eth_hdr;
- //--- ip header - 20 bytes ---
- volatile struct{
- uint32_t ver_ihl_tos; //word 9
- uint32_t total_length;
- uint32_t identification;
- uint32_t flags_frag_off;
- uint32_t ttl_proto;
- uint32_t checksum;
- uint32_t src_addr_high;
- uint32_t src_addr_low;
- uint32_t dst_addr_high;
- uint32_t dst_addr_low; //word 18
- } ip_hdr;
- //--- udp header - 8 bytes ---
- volatile struct{
- uint32_t src_port; //word 19
- uint32_t dst_port;
- uint32_t length;
- uint32_t checksum; //word 22
- } udp_hdr;
- volatile uint32_t _pad[1];
- volatile uint32_t dsp0_port;
- volatile uint32_t err0_port;
- volatile uint32_t dsp1_port;
- volatile uint32_t err1_port;
-} sr_udp_sm_t;
-
-// control bits (all expect UDP_SM_LAST_WORD are mutually exclusive)
-
-// Insert a UDP source port from the table
-#define UDP_SM_INS_UDP_SRC_PORT (1 << 21)
-
-// Insert a UDP dest port from the table
-#define UDP_SM_INS_UDP_DST_PORT (1 << 20)
-
-// This is the last word of the header
-#define UDP_SM_LAST_WORD (1 << 19)
-
-// Insert IP header checksum here. Data is the xor of 16'hFFFF and
-// the values written into regs 9-13 and 15-18.
-#define UDP_SM_INS_IP_HDR_CHKSUM (1 << 18)
-
-// Insert IP Length here (data ignored)
-#define UDP_SM_INS_IP_LEN (1 << 17)
-
-// Insert UDP Length here (data ignore)
-#define UDP_SM_INS_UDP_LEN (1 << 16)
-
-#define sr_udp_sm ((sr_udp_sm_t *) _SR_ADDR(SR_UDP_SM))
+typedef struct{
+ struct{
+ volatile uint32_t entry[16];
+ } table[4];
+} sr_proto_framer_t;
+
+#define sr_proto_framer_regs ((sr_proto_framer_t *) _SR_ADDR(SR_UDP_SM))
// --- VITA TX CTRL regs ---
diff --git a/firmware/zpu/lib/net_common.c b/firmware/zpu/lib/net_common.c
index f70f279ac..895b7b942 100644
--- a/firmware/zpu/lib/net_common.c
+++ b/firmware/zpu/lib/net_common.c
@@ -36,17 +36,40 @@
#include <string.h>
#include "pkt_ctrl.h"
+/***********************************************************************
+ * Constants + Globals
+ **********************************************************************/
static const bool debug = false;
-
static const size_t out_buff_size = 2048;
-
static const eth_mac_addr_t BCAST_MAC_ADDR = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
+#define MAX_UDP_LISTENERS 6
//used in the top level application...
uint16_t dsp0_dst_port, err0_dst_port, dsp1_dst_port;
-// ------------------------------------------------------------------------
+/***********************************************************************
+ * Checksum routines
+ **********************************************************************/
+static unsigned int CHKSUM(unsigned int x, unsigned int *chksum){
+ *chksum += x;
+ *chksum = (*chksum & 0xffff) + (*chksum>>16);
+ *chksum = (*chksum & 0xffff) + (*chksum>>16);
+ return x;
+}
+
+static unsigned int chksum_buffer(
+ unsigned short *buf, int nshorts,
+ unsigned int initial_chksum
+){
+ unsigned int chksum = initial_chksum;
+ for (int i = 0; i < nshorts; i++) CHKSUM(buf[i], &chksum);
+
+ return chksum;
+}
+/***********************************************************************
+ * Listener registry
+ **********************************************************************/
static eth_mac_addr_t _local_mac_addr;
static struct ip_addr _local_ip_addr;
void register_addrs(const eth_mac_addr_t *mac_addr, const struct ip_addr *ip_addr){
@@ -54,10 +77,6 @@ void register_addrs(const eth_mac_addr_t *mac_addr, const struct ip_addr *ip_add
_local_ip_addr = *ip_addr;
}
-//-------------------------------------------------------------------------
-
-#define MAX_UDP_LISTENERS 6
-
struct listener_entry {
unsigned short port;
udp_receiver_t rcvr;
@@ -104,9 +123,55 @@ register_udp_listener(int port, udp_receiver_t rcvr)
}
}
-// ------------------------------------------------------------------------
+/***********************************************************************
+ * Protocol framer
+ **********************************************************************/
+void setup_framer(
+ eth_mac_addr_t eth_dst,
+ eth_mac_addr_t eth_src,
+ struct socket_address sock_dst,
+ struct socket_address sock_src,
+ size_t which
+){
+ struct {
+ padded_eth_hdr_t eth;
+ struct ip_hdr ip;
+ struct udp_hdr udp;
+ } frame;
+
+ //-- load Ethernet header --//
+ frame.eth.dst = eth_dst;
+ frame.eth.src = eth_src;
+ frame.eth.ethertype = ETHERTYPE_IPV4;
+
+ //-- load IPv4 header --//
+ IPH_VHLTOS_SET(&frame.ip, 4, 5, 0);
+ IPH_LEN_SET(&frame.ip, 0);
+ IPH_ID_SET(&frame.ip, 0);
+ IPH_OFFSET_SET(&frame.ip, IP_DF); // don't fragment
+ const int ttl = 32;
+ frame.ip._ttl_proto = (ttl << 8) | (IP_PROTO_UDP & 0xff);
+ frame.ip._chksum = 0;
+ frame.ip.src = sock_src.addr;
+ frame.ip.dest = sock_dst.addr;
+ frame.ip._chksum = ~chksum_buffer(
+ (unsigned short *) &frame.ip,
+ sizeof(frame.ip)/sizeof(short), 0
+ );
+
+ //-- load UDP header --//
+ frame.udp.src = sock_src.port;
+ frame.udp.dest = sock_dst.port;
+ frame.udp.len = 0;
+ frame.udp.chksum = 0;
+ //copy into the framer table registers
+ memcpy_wa((void *)(sr_proto_framer_regs->table[which].entry + 1), &frame, sizeof(frame));
+}
+/***********************************************************************
+ * Slow-path packet framing and transmission
+ **********************************************************************/
/*!
* low level routine to assembly an ethernet frame and send it.
*
@@ -164,24 +229,6 @@ send_pkt(
if (debug) printf("sent %d bytes\n", (int)total_len);
}
-unsigned int CHKSUM(unsigned int x, unsigned int *chksum)
-{
- *chksum += x;
- *chksum = (*chksum & 0xffff) + (*chksum>>16);
- *chksum = (*chksum & 0xffff) + (*chksum>>16);
- return x;
-}
-
-static unsigned int
-chksum_buffer(unsigned short *buf, int nshorts, unsigned int initial_chksum)
-{
- unsigned int chksum = initial_chksum;
- for (int i = 0; i < nshorts; i++)
- CHKSUM(buf[i], &chksum);
-
- return chksum;
-}
-
void
send_ip_pkt(struct ip_addr dst, int protocol,
const void *buf0, size_t len0,
diff --git a/firmware/zpu/lib/net_common.h b/firmware/zpu/lib/net_common.h
index 409022352..3cbc5c514 100644
--- a/firmware/zpu/lib/net_common.h
+++ b/firmware/zpu/lib/net_common.h
@@ -1,6 +1,5 @@
-/* -*- c++ -*- */
/*
- * Copyright 2009,2010 Ettus Research LLC
+ * Copyright 2009-2011 Ettus Research LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,12 +22,22 @@
#include <net/socket_address.h>
#include <net/eth_mac_addr.h>
-/*
- * 1's complement sum for IP and UDP headers
+/*!
+ * Setup an entry in the protocol framer for a UDP socket.
*
- * init chksum to zero to start.
+ * \param eth_dst ethernet destination mac addr
+ * \param eth_src ethernet source mac addr
+ * \param sock_dst udp/ip socket destination
+ * \param sock_src udp/ip socket source
+ * \param which the index into the table
*/
-unsigned int CHKSUM(unsigned int x, unsigned int *chksum);
+void setup_framer(
+ eth_mac_addr_t eth_dst,
+ eth_mac_addr_t eth_src,
+ struct socket_address sock_dst,
+ struct socket_address sock_src,
+ size_t which
+);
typedef void (*udp_receiver_t)(struct socket_address src, struct socket_address dst,
unsigned char *payload, int payload_len);