usrp2: moved sregs in fw memory map, new framer register table

This commit is contained in:
Josh Blum 2011-03-15 19:17:59 -07:00
parent 77481462d1
commit d47bc1e06c
4 changed files with 160 additions and 231 deletions

View file

@ -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"
//network headers
#include "arp_cache.h"
#include "ethernet.h"
#include "net_common.h"
#include "usrp2/fw_common.h"
#include "udp_fw_update.h"
#include "pkt_ctrl.h"
//standard headers
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "clocks.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"
#include <stdbool.h>
static void setup_network(void);
// ----------------------------------------------------------------
// 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();
case USRP2_UDP_ERR0_PORT:
which = 1;
err0_dst_port = src.port;
break;
//setup network
setup_network();
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

View file

@ -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_MISC 0 // 7 regs
#define SR_SIMTIMER 8 // 2
#define SR_TIME64 10 // 6
#define SR_BUF_POOL 16 // 4
#define _SR_ADDR(sr) (MISC_OUTPUT_BASE + (sr) * sizeof(uint32_t))
#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;
typedef struct{
struct{
volatile uint32_t entry[16];
} table[4];
} sr_proto_framer_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))
#define sr_proto_framer_regs ((sr_proto_framer_t *) _SR_ADDR(SR_UDP_SM))
// --- VITA TX CTRL regs ---

View file

@ -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,

View file

@ -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);