diff options
Diffstat (limited to 'firmware/zpu/lib')
-rw-r--r-- | firmware/zpu/lib/eth_mac_regs.h | 62 | ||||
-rw-r--r-- | firmware/zpu/lib/memory_map.h | 462 | ||||
-rw-r--r-- | firmware/zpu/lib/net_common.c | 108 | ||||
-rw-r--r-- | firmware/zpu/lib/net_common.h | 21 |
4 files changed, 552 insertions, 101 deletions
diff --git a/firmware/zpu/lib/eth_mac_regs.h b/firmware/zpu/lib/eth_mac_regs.h deleted file mode 100644 index d680f8de0..000000000 --- a/firmware/zpu/lib/eth_mac_regs.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- c -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef INCLUDED_ETH_MAC_REGS_H -#define INCLUDED_ETH_MAC_REGS_H - -/* - * Simple GEMAC - * - */ -typedef struct { - volatile int settings; - volatile int ucast_hi; - volatile int ucast_lo; - volatile int mcast_hi; - volatile int mcast_lo; - volatile int miimoder; - volatile int miiaddress; - volatile int miitx_data; - volatile int miicommand; - volatile int miistatus; - volatile int miirx_data; - volatile int pause_time; - volatile int pause_thresh; -} eth_mac_regs_t; - -// settings register -#define MAC_SET_PAUSE_EN (1 << 0) // Makes us respect received pause frames (normally on) -#define MAC_SET_PASS_ALL (1 << 1) // Enables promiscuous mode, currently broken -#define MAC_SET_PASS_PAUSE (1 << 2) // Sends pause frames through (normally off) -#define MAC_SET_PASS_BCAST (1 << 3) // Sends broadcast frames through (normally on) -#define MAC_SET_PASS_MCAST (1 << 4) // Sends multicast frames that match mcast addr (normally off) -#define MAC_SET_PASS_UCAST (1 << 5) // Sends unicast (normal) frames through if they hit in address filter (normally on) -#define MAC_SET_PAUSE_SEND_EN (1 << 6) // Enables sending pause frames - -// miicommand register -#define MIIC_SCANSSTAT (1 << 0) // Scan status -#define MIIC_RSTAT (1 << 1) // Read status -#define MIIC_WCTRLDATA (1 << 2) // Write control data - -// miistatus register -#define MIIS_LINKFAIL (1 << 0) // The link failed -#define MIIS_BUSY (1 << 1) // The MII is busy (operation in progress) -#define MIIS_NVALID (1 << 2) // The data in the status register is invalid - // This it is only valid when the scan status is active. - -#endif /* INCLUDED_ETH_MAC_REGS_H */ diff --git a/firmware/zpu/lib/memory_map.h b/firmware/zpu/lib/memory_map.h new file mode 100644 index 000000000..938cf7776 --- /dev/null +++ b/firmware/zpu/lib/memory_map.h @@ -0,0 +1,462 @@ +// Copyright 2010-2011 Ettus Research LLC +/* + * Copyright 2007,2008,2009 Free Software Foundation, Inc. + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef INCLUDED_MEMORY_MAP_H +#define INCLUDED_MEMORY_MAP_H + +#include <stdint.h> + +#define MASTER_CLK_RATE 100000000 // 100 MHz + +//////////////////////////////////////////////////////////////////////// +// Define slave bases +//////////////////////////////////////////////////////////////////////// +#define ROUTER_RAM_BASE 0x4000 +#define SPI_BASE 0x5000 +#define I2C_BASE 0x5400 +#define GPIO_BASE 0x5800 +#define READBACK_BASE 0x5C00 +#define ETH_BASE 0x6000 +#define SETTING_REGS_BASE 0x7000 +#define PIC_BASE 0x8000 +#define UART_BASE 0x8800 +#define ATR_BASE 0x8C00 +#ifdef USRP2 +#define SDSPI_BASE 0xB000 +#endif +#ifdef USRP2P +#define ICAP_BASE 0xA000 +#define SPIF_BASE 0xB000 +#define RAM_BASE 0xC000 +#endif + +///////////////////////////////////////////////////// +// SPI Core, Slave 2. See core docs for more info +///////////////////////////////////////////////////// + +typedef struct { + volatile uint32_t txrx0; + volatile uint32_t txrx1; + volatile uint32_t txrx2; + volatile uint32_t txrx3; + volatile uint32_t ctrl; + volatile uint32_t div; + volatile uint32_t ss; +} spi_regs_t; + +#define spi_regs ((spi_regs_t *) SPI_BASE) + +// Masks for controlling different peripherals +#define SPI_SS_AD9510 1 +#define SPI_SS_AD9777 2 +#define SPI_SS_RX_DAC 4 +#define SPI_SS_RX_ADC 8 +#define SPI_SS_RX_DB 16 +#define SPI_SS_TX_DAC 32 +#define SPI_SS_TX_ADC 64 +#define SPI_SS_TX_DB 128 +#define SPI_SS_ADS62P44 256 + +// Masks for different parts of CTRL reg +#define SPI_CTRL_ASS (1<<13) +#define SPI_CTRL_IE (1<<12) +#define SPI_CTRL_LSB (1<<11) +#define SPI_CTRL_TXNEG (1<<10) +#define SPI_CTRL_RXNEG (1<< 9) +#define SPI_CTRL_GO_BSY (1<< 8) +#define SPI_CTRL_CHAR_LEN_MASK 0x7F + +//////////////////////////////////////////////// +// I2C, Slave 3 +//////////////////////////////////////////////// + +typedef struct { + volatile uint32_t prescaler_lo; // r/w + volatile uint32_t prescaler_hi; // r/w + volatile uint32_t ctrl; // r/w + volatile uint32_t data; // wr = transmit reg; rd = receive reg + volatile uint32_t cmd_status; // wr = command reg; rd = status reg +} i2c_regs_t; + +#define i2c_regs ((i2c_regs_t *) I2C_BASE) + +#define I2C_CTRL_EN (1 << 7) // core enable +#define I2C_CTRL_IE (1 << 6) // interrupt enable + +// +// STA, STO, RD, WR, and IACK bits are cleared automatically +// +#define I2C_CMD_START (1 << 7) // generate (repeated) start condition +#define I2C_CMD_STOP (1 << 6) // generate stop condition +#define I2C_CMD_RD (1 << 5) // read from slave +#define I2C_CMD_WR (1 << 4) // write to slave +#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1) +#define I2C_CMD_RSVD_2 (1 << 2) // reserved +#define I2C_CMD_RSVD_1 (1 << 1) // reserved +#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt + +#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK) +#define I2C_ST_BUSY (1 << 6) // 1 after START signal detected; 0 after STOP signal detected +#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration +#define I2C_ST_RSVD_4 (1 << 4) // reserved +#define I2C_ST_RSVD_3 (1 << 3) // reserved +#define I2C_ST_RSVD_2 (1 << 2) // reserved +#define I2C_ST_TIP (1 << 1) // Transfer-in-progress +#define I2C_ST_IP (1 << 0) // Interrupt pending + +/////////////////////////////////////////////////// +// Packet Router Status, Slave 5 +/////////////////////////////////////////////////// + +typedef struct { + volatile uint32_t _padding[8]; + volatile uint32_t status; + volatile uint32_t hw_config; // see below + volatile uint32_t time64_secs_rb; + volatile uint32_t time64_ticks_rb; + volatile uint32_t compat_num; + volatile uint32_t irqs; +} router_status_t; + +#define router_status ((router_status_t *) READBACK_BASE) + +// The hw_config register + +#define HWC_SIMULATION 0x80000000 +#define HWC_WB_CLK_DIV_MASK 0x0000000f + +/*! + * \brief return non-zero if we're running under the simulator + */ +inline static int +hwconfig_simulation_p(void) +{ + return router_status->hw_config & HWC_SIMULATION; +} + +/*! + * \brief Return Wishbone Clock divisor. + * The processor runs at the Wishbone Clock rate which is MASTER_CLK_RATE / divisor. + */ +inline static int +hwconfig_wishbone_divisor(void) +{ + return router_status->hw_config & HWC_WB_CLK_DIV_MASK; +} + +/////////////////////////////////////////////////// +// Ethernet Core, Slave 6 +/////////////////////////////////////////////////// + +typedef struct { + volatile int settings; + volatile int ucast_hi; + volatile int ucast_lo; + volatile int mcast_hi; + volatile int mcast_lo; + volatile int miimoder; + volatile int miiaddress; + volatile int miitx_data; + volatile int miicommand; + volatile int miistatus; + volatile int miirx_data; + volatile int pause_time; + volatile int pause_thresh; +} eth_mac_regs_t; + +// settings register +#define MAC_SET_PAUSE_EN (1 << 0) // Makes us respect received pause frames (normally on) +#define MAC_SET_PASS_ALL (1 << 1) // Enables promiscuous mode, currently broken +#define MAC_SET_PASS_PAUSE (1 << 2) // Sends pause frames through (normally off) +#define MAC_SET_PASS_BCAST (1 << 3) // Sends broadcast frames through (normally on) +#define MAC_SET_PASS_MCAST (1 << 4) // Sends multicast frames that match mcast addr (normally off) +#define MAC_SET_PASS_UCAST (1 << 5) // Sends unicast (normal) frames through if they hit in address filter (normally on) +#define MAC_SET_PAUSE_SEND_EN (1 << 6) // Enables sending pause frames + +// miicommand register +#define MIIC_SCANSSTAT (1 << 0) // Scan status +#define MIIC_RSTAT (1 << 1) // Read status +#define MIIC_WCTRLDATA (1 << 2) // Write control data + +// miistatus register +#define MIIS_LINKFAIL (1 << 0) // The link failed +#define MIIS_BUSY (1 << 1) // The MII is busy (operation in progress) +#define MIIS_NVALID (1 << 2) // The data in the status register is invalid + // This it is only valid when the scan status is active. + +#define eth_mac ((eth_mac_regs_t *) ETH_BASE) + +//////////////////////////////////////////////////// +// Settings Bus, Slave #7, Not Byte Addressable! +// +// Output-only from processor point-of-view. +// 1KB of address space (== 256 32-bit write-only regs) +//////////////////////////////////////////////////// + +#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) (SETTING_REGS_BASE + (sr) * sizeof(uint32_t)) + +#define SR_ADDR_BLDRDONE _SR_ADDR(5) + +// --- packet router control regs --- + +typedef struct { + volatile uint32_t mode_ctrl; + volatile uint32_t ip_addr; + volatile uint32_t data_ports; //dsp0 (low 16) dsp1 (high 16) + volatile uint32_t iface_ctrl; +} router_ctrl_t; + +#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 led_src; // HW or SW control for LEDs + volatile uint32_t flush_icache; // Flush the icache +} output_regs_t; + +#define CLK_RESET (1<<4) +#define CLK_ENABLE (1<<3) | (1<<2) +#define CLK_SEL (1<<1) | (1<<0) + +#define SERDES_ENABLE 8 +#define SERDES_PRBSEN 4 +#define SERDES_LOOPEN 2 +#define SERDES_RXEN 1 + +#define ADC_CTRL_ON 0x0F +#define ADC_CTRL_OFF 0x00 + +// crazy order that matches the labels on the case + +#define LED_A (1 << 4) +#define LED_B (1 << 1) +#define LED_E (1 << 2) +#define LED_D (1 << 0) +#define LED_C (1 << 3) +// LED_F // controlled by CPLD +#define LED_RJ45 (1 << 5) + +#define output_regs ((output_regs_t *) SETTING_REGS_BASE) + +// --- protocol framer regs --- + +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 --- + +typedef struct { + volatile uint32_t num_chan; + volatile uint32_t clear_state; // clears out state machine, fifos, + volatile uint32_t report_sid; + volatile uint32_t policy; + volatile uint32_t cyc_per_up; + volatile uint32_t packets_per_up; +} sr_tx_ctrl_t; + +#define sr_tx_ctrl ((sr_tx_ctrl_t *) _SR_ADDR(SR_TX_CTRL)) + +// --- VITA RX CTRL regs --- +typedef struct { + // The following 3 are logically a single command register. + // They are clocked into the underlying fifo when time_ticks is written. + volatile uint32_t cmd; // {now, chain, num_samples(30) + volatile uint32_t time_secs; + volatile uint32_t time_ticks; +} sr_rx_ctrl_t; + +#define sr_rx_ctrl0 ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL0)) +#define sr_rx_ctrl1 ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL1)) + +// ---------------------------------------------------------------- +// VITA49 64 bit time (write only) + /*! + * \brief Time 64 flags + * + * <pre> + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------------------------------------------------------+-+-+ + * | |S|P| + * +-----------------------------------------------------------+-+-+ + * + * P - PPS edge selection (0=negedge, 1=posedge, default=0) + * S - Source (0=sma, 1=mimo, 0=default) + * + * </pre> + */ +typedef struct { + volatile uint32_t secs; // value to set absolute secs to on next PPS + volatile uint32_t ticks; // value to set absolute ticks to on next PPS + volatile uint32_t flags; // flags - see chart above + volatile uint32_t imm; // set immediate (0=latch on next pps, 1=latch immediate, default=0) +} sr_time64_t; + +#define sr_time64 ((sr_time64_t *) _SR_ADDR(SR_TIME64)) + +/////////////////////////////////////////////////////// +// Simple Programmable Interrupt Controller, Slave 8 +/////////////////////////////////////////////////////// + +// Interrupt request lines +// Bit numbers (LSB == 0) that correpond to interrupts into PIC + +#define IRQ_BUFFER 0 // buffer manager +#define IRQ_ONETIME 1 +#define IRQ_SPI 2 +#define IRQ_I2C 3 +#define IRQ_PHY 4 // ethernet PHY +#define IRQ_UNDERRUN 5 +#define IRQ_OVERRUN 6 +#define IRQ_PPS 7 // pulse per second +#define IRQ_UART_RX 8 +#define IRQ_UART_TX 9 +#define IRQ_SERDES 10 +#define IRQ_CLKSTATUS 11 +#define IRQ_PERIODIC 12 +#define IRQ_BUTTON 13 + +#define IRQ_TO_MASK(x) (1 << (x)) + +#define PIC_BUFFER_INT IRQ_TO_MASK(IRQ_BUFFER) +#define PIC_ONETIME_INT IRQ_TO_MASK(IRQ_ONETIME) +#define PIC_SPI_INT IRQ_TO_MASK(IRQ_SPI) +#define PIC_I2C_INT IRQ_TO_MASK(IRQ_I2C) +#define PIC_PHY_INT IRQ_TO_MASK(IRQ_PHY) +#define PIC_UNDERRUN_INT IRQ_TO_MASK(IRQ_UNDERRUN) +#define PIC_OVERRUN_INT IRQ_TO_MASK(IRQ_OVERRUN) +#define PIC_PPS_INT IRQ_TO_MASK(IRQ_PPS) +#define PIC_UART_RX_INT IRQ_TO_MASK(IRQ_UART_RX) +#define PIC_UART_TX_INT IRQ_TO_MASK(IRQ_UART_TX) +#define PIC_SERDES IRQ_TO_MASK(IRQ_SERDES) +#define PIC_CLKSTATUS IRQ_TO_MASK(IRQ_CLKSTATUS) +#define PIC_BUTTON IRQ_TO_MASK(IRQ_BUTTON) + +typedef struct { + volatile uint32_t edge_enable; // mask: 1 -> edge triggered, 0 -> level + volatile uint32_t polarity; // mask: 1 -> rising edge + volatile uint32_t mask; // mask: 1 -> disabled + volatile uint32_t pending; // mask: 1 -> pending; write 1's to clear pending ints +} pic_regs_t; + +#define pic_regs ((pic_regs_t *) PIC_BASE) + +// ---------------------------------------------------------------- +// WB_CLK_RATE is the time base for this +typedef struct { + volatile uint32_t onetime; // Number of wb clk cycles till the onetime interrupt + volatile uint32_t periodic; // Repeat rate of periodic interrupt +} sr_simple_timer_t; + +#define sr_simple_timer ((sr_simple_timer_t *) _SR_ADDR(SR_SIMTIMER)) + +/////////////////////////////////////////////////// +// UART, Slave 10 +/////////////////////////////////////////////////// + +typedef struct { + // All elements are 8 bits except for clkdiv (16), but we use uint32 to make + // the hardware for decoding easier + volatile uint32_t clkdiv; // Set to 50e6 divided by baud rate (no x16 factor) + volatile uint32_t txlevel; // Number of spaces in the FIFO for writes + volatile uint32_t rxlevel; // Number of available elements in the FIFO for reads + volatile uint32_t txchar; // Write characters to be sent here + volatile uint32_t rxchar; // Read received characters here +} uart_regs_t; + +#define uart_regs ((uart_regs_t *) UART_BASE) + +/////////////////////////////////////////////////// +// SD Card SPI interface, Slave 13 +// All regs are 8 bits wide, but are accessed as if they are 32 bits +/////////////////////////////////////////////////// +#ifdef USRP2 + +typedef struct { + volatile uint32_t status; // Write a 1 or 0 for controlling CS + volatile uint32_t clkdiv; + volatile uint32_t send_dat; + volatile uint32_t receive_dat; +} sdspi_regs_t; + +#define sdspi_regs ((sdspi_regs_t *) SDSPI_BASE) + +#endif //USRP2 + +/////////////////////////////////////////////////// +// ICAP, Slave 13 +/////////////////////////////////////////////////// +#ifdef USRP2P + +typedef struct { + uint32_t icap; //only the lower 8 bits matter +} icap_regs_t; + +#define icap_regs ((icap_regs_t *) ICAP_BASE) + +/////////////////////////////////////////////////// +// SPI Flash interface, Slave 14 +// Control register definitions are the same as SPI, so use SPI_CTRL_ASS, etc. +// Peripheral mask not needed since bus is dedicated (CE held low) +/////////////////////////////////////////////////// + +typedef struct { + volatile uint32_t txrx0; + volatile uint32_t txrx1; + volatile uint32_t txrx2; + volatile uint32_t txrx3; + volatile uint32_t ctrl; + volatile uint32_t div; + volatile uint32_t ss; +} spif_regs_t; + +#define spif_regs ((spif_regs_t *) SPIF_BASE) + +#endif //USRP2P + +#endif /* INCLUDED_MEMORY_MAP_H */ diff --git a/firmware/zpu/lib/net_common.c b/firmware/zpu/lib/net_common.c index f70f279ac..2e3257b35 100644 --- a/firmware/zpu/lib/net_common.c +++ b/firmware/zpu/lib/net_common.c @@ -36,17 +36,35 @@ #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; -// ------------------------------------------------------------------------ +/*********************************************************************** + * 16-bit one's complement sum + **********************************************************************/ +static uint32_t chksum_buffer( + uint16_t *buf, size_t nshorts, + uint32_t initial_chksum +){ + uint32_t chksum = initial_chksum; + for (size_t i = 0; i < nshorts; i++) chksum += buf[i]; + + while (chksum >> 16) chksum = (chksum & 0xffff) + (chksum >> 16); + + 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 +72,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 +118,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 + IPH_TTL_SET(&frame.ip, 32); + IPH_PROTO_SET(&frame.ip, IP_PROTO_UDP); + IPH_CHKSUM_SET(&frame.ip, 0); + frame.ip.src = sock_src.addr; + frame.ip.dest = sock_dst.addr; + IPH_CHKSUM_SET(&frame.ip, 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,43 +224,25 @@ 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, const void *buf1, size_t len1) { - int ttl = 32; - struct ip_hdr ip; IPH_VHLTOS_SET(&ip, 4, 5, 0); IPH_LEN_SET(&ip, IP_HLEN + len0 + len1); IPH_ID_SET(&ip, 0); IPH_OFFSET_SET(&ip, IP_DF); /* don't fragment */ - ip._ttl_proto = (ttl << 8) | (protocol & 0xff); - ip._chksum = 0; + IPH_TTL_SET(&ip, 32); + IPH_PROTO_SET(&ip, protocol); + IPH_CHKSUM_SET(&ip, 0); ip.src = _local_ip_addr; ip.dest = dst; - ip._chksum = ~chksum_buffer((unsigned short *) &ip, - sizeof(ip)/sizeof(short), 0); + IPH_CHKSUM_SET(&ip, ~chksum_buffer( + (unsigned short *) &ip, sizeof(ip)/sizeof(short), 0 + )); eth_mac_addr_t dst_mac; bool found = arp_cache_lookup_mac(&ip.dest, &dst_mac); 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); |