summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/microblaze/apps/txrx_uhd.c12
-rw-r--r--firmware/microblaze/lib/Makefile.inc1
-rw-r--r--firmware/microblaze/lib/eth_addrs.c119
-rw-r--r--firmware/microblaze/lib/net_common.c16
-rw-r--r--firmware/microblaze/lib/net_common.h2
-rw-r--r--firmware/microblaze/usrp2/Makefile.am3
-rw-r--r--firmware/microblaze/usrp2/ethernet.c99
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp8
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp8
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp3
-rw-r--r--images/Makefile1
11 files changed, 167 insertions, 105 deletions
diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c
index 1dd6e80ac..b7837f207 100644
--- a/firmware/microblaze/apps/txrx_uhd.c
+++ b/firmware/microblaze/apps/txrx_uhd.c
@@ -422,6 +422,7 @@ link_changed_callback(int speed)
link_is_up = speed != 0;
hal_set_leds(link_is_up ? LED_RJ45 : 0x0, LED_RJ45);
printf("\neth link changed: speed = %d\n", speed);
+ if (link_is_up) send_gratuitous_arp();
}
static void setup_network(void){
@@ -479,15 +480,18 @@ main(void)
printf("FPGA compatibility number: %d\n", USRP2_FPGA_COMPAT_NUM);
printf("Firmware compatibility number: %d\n", USRP2_FW_COMPAT_NUM);
- ethernet_register_link_changed_callback(link_changed_callback);
- ethernet_init();
-
+ //1) register the addresses into the network stack
register_mac_addr(ethernet_mac_addr());
register_ip_addr(get_ip_addr());
+ //2) register callbacks for udp ports we service
register_udp_listener(USRP2_UDP_CTRL_PORT, handle_udp_ctrl_packet);
register_udp_listener(USRP2_UDP_DATA_PORT, handle_udp_data_packet);
+ //3) setup ethernet hardware to bring the link up
+ ethernet_register_link_changed_callback(link_changed_callback);
+ ethernet_init();
+
// initialize double buffering state machine for ethernet -> DSP Tx
dbsm_init(&dsp_tx_sm, DSP_TX_BUF_0,
@@ -536,7 +540,7 @@ main(void)
}
if (pending & PIC_OVERRUN_INT){
- dbsm_handle_rx_overrun(&dsp_rx_sm);
+ //dbsm_handle_rx_overrun(&dsp_rx_sm);
pic_regs->pending = PIC_OVERRUN_INT; // clear pending interrupt
// FIXME Figure out how to handle this robustly.
diff --git a/firmware/microblaze/lib/Makefile.inc b/firmware/microblaze/lib/Makefile.inc
index a576d1ccb..2b5685d3f 100644
--- a/firmware/microblaze/lib/Makefile.inc
+++ b/firmware/microblaze/lib/Makefile.inc
@@ -26,6 +26,7 @@ COMMON_SRCS = \
$(top_srcdir)/lib/clocks.c \
$(top_srcdir)/lib/dbsm.c \
$(top_srcdir)/lib/eeprom.c \
+ $(top_srcdir)/lib/eth_addrs.c \
$(top_srcdir)/lib/eth_mac.c \
$(top_srcdir)/lib/_exit.c \
$(top_srcdir)/lib/exit.c \
diff --git a/firmware/microblaze/lib/eth_addrs.c b/firmware/microblaze/lib/eth_addrs.c
new file mode 100644
index 000000000..d7c1e0394
--- /dev/null
+++ b/firmware/microblaze/lib/eth_addrs.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2010 Ettus Research LLC
+ * 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/>.
+ */
+
+#include "ethernet.h"
+#include "memory_map.h"
+#include "nonstdio.h"
+#include <stdbool.h>
+#include "i2c.h"
+#include "usrp2/fw_common.h"
+
+static bool
+unprogrammed(const void *t, size_t len)
+{
+ int i;
+ uint8_t *p = (uint8_t *)t;
+ bool all_zeros = true;
+ bool all_ones = true;
+ for (i = 0; i < len; i++){
+ all_zeros &= p[i] == 0x00;
+ all_ones &= p[i] == 0xff;
+ }
+ return all_ones | all_zeros;
+}
+
+//////////////////// MAC Addr Stuff ///////////////////////
+
+static int8_t src_mac_addr_initialized = false;
+static eth_mac_addr_t src_mac_addr = {{
+ 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff
+ }};
+
+const eth_mac_addr_t *
+ethernet_mac_addr(void)
+{
+ if (!src_mac_addr_initialized){ // fetch from eeprom
+ src_mac_addr_initialized = true;
+
+ // if we're simulating, don't read the EEPROM model, it's REALLY slow
+ if (hwconfig_simulation_p())
+ return &src_mac_addr;
+
+ eth_mac_addr_t tmp;
+ bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, &tmp, sizeof(tmp));
+ if (!ok || unprogrammed(&tmp, sizeof(tmp))){
+ // use the default
+ }
+ else
+ src_mac_addr = tmp;
+ }
+
+ return &src_mac_addr;
+}
+
+bool
+ethernet_set_mac_addr(const eth_mac_addr_t *t)
+{
+ bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, t, sizeof(eth_mac_addr_t));
+ if (ok){
+ src_mac_addr = *t;
+ src_mac_addr_initialized = true;
+ //eth_mac_set_addr(t); //this breaks the link
+ }
+
+ return ok;
+}
+
+//////////////////// IP Addr Stuff ///////////////////////
+
+static int8_t src_ip_addr_initialized = false;
+static struct ip_addr src_ip_addr = {
+ (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)
+};
+
+
+const struct ip_addr *get_ip_addr(void)
+{
+ if (!src_ip_addr_initialized){ // fetch from eeprom
+ src_ip_addr_initialized = true;
+
+ // if we're simulating, don't read the EEPROM model, it's REALLY slow
+ if (hwconfig_simulation_p())
+ return &src_ip_addr;
+
+ struct ip_addr tmp;
+ bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, &tmp, sizeof(tmp));
+ if (!ok || unprogrammed(&tmp, sizeof(tmp))){
+ // use the default
+ }
+ else
+ src_ip_addr = tmp;
+ }
+
+ return &src_ip_addr;
+}
+
+bool set_ip_addr(const struct ip_addr *t){
+ bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, t, sizeof(struct ip_addr));
+ if (ok){
+ src_ip_addr = *t;
+ src_ip_addr_initialized = true;
+ }
+
+ return ok;
+}
diff --git a/firmware/microblaze/lib/net_common.c b/firmware/microblaze/lib/net_common.c
index 6c9509c92..beaaa5948 100644
--- a/firmware/microblaze/lib/net_common.c
+++ b/firmware/microblaze/lib/net_common.c
@@ -351,6 +351,22 @@ send_arp_reply(struct arp_eth_ipv4 *req, eth_mac_addr_t our_mac)
send_pkt(t, ETHERTYPE_ARP, &reply, sizeof(reply), 0, 0, 0, 0);
}
+void send_gratuitous_arp(void){
+ struct arp_eth_ipv4 req _AL4;
+ req.ar_hrd = ARPHRD_ETHER;
+ req.ar_pro = ETHERTYPE_IPV4;
+ req.ar_hln = sizeof(eth_mac_addr_t);
+ req.ar_pln = sizeof(struct ip_addr);
+ req.ar_op = ARPOP_REQUEST;
+ memcpy(req.ar_sha, ethernet_mac_addr(), sizeof(eth_mac_addr_t));
+ memcpy(req.ar_sip, get_ip_addr(), sizeof(struct ip_addr));
+ memset(req.ar_tha, 0x00, sizeof(eth_mac_addr_t));
+ memcpy(req.ar_tip, get_ip_addr(), sizeof(struct ip_addr));
+
+ //send the request with a broadcast ethernet mac address
+ eth_mac_addr_t t; memset(&t, 0xff, sizeof(t));
+ send_pkt(t, ETHERTYPE_ARP, &req, sizeof(req), 0, 0, 0, 0);
+}
static void
handle_arp_packet(struct arp_eth_ipv4 *p, size_t size)
diff --git a/firmware/microblaze/lib/net_common.h b/firmware/microblaze/lib/net_common.h
index 112669b46..3040e5ef3 100644
--- a/firmware/microblaze/lib/net_common.h
+++ b/firmware/microblaze/lib/net_common.h
@@ -47,4 +47,6 @@ void send_udp_pkt(int src_port, struct socket_address dst,
void handle_eth_packet(uint32_t *p, size_t nlines);
+void send_gratuitous_arp(void);
+
#endif /* INCLUDED_NET_COMMON_H */
diff --git a/firmware/microblaze/usrp2/Makefile.am b/firmware/microblaze/usrp2/Makefile.am
index 8da013980..ba426b75c 100644
--- a/firmware/microblaze/usrp2/Makefile.am
+++ b/firmware/microblaze/usrp2/Makefile.am
@@ -22,10 +22,11 @@ AM_CFLAGS = \
AM_LDFLAGS = \
$(COMMON_LFLAGS) \
- libusrp2.a \
-Wl,-defsym -Wl,_TEXT_START_ADDR=0x0050 \
-Wl,-defsym -Wl,_STACK_SIZE=3072
+LDADD = libusrp2.a
+
########################################################################
# USRP2 specific library and programs
########################################################################
diff --git a/firmware/microblaze/usrp2/ethernet.c b/firmware/microblaze/usrp2/ethernet.c
index d60d7dc4c..5d4654bda 100644
--- a/firmware/microblaze/usrp2/ethernet.c
+++ b/firmware/microblaze/usrp2/ethernet.c
@@ -16,16 +16,12 @@
*/
#include "ethernet.h"
-#include "memory_map.h"
#include "eth_phy.h"
#include "eth_mac.h"
#include "eth_mac_regs.h"
#include "pic.h"
#include "hal_io.h"
#include "nonstdio.h"
-#include <stdbool.h>
-#include "i2c.h"
-#include "usrp2/fw_common.h"
#define VERBOSE 1
@@ -269,101 +265,6 @@ ethernet_init(void)
eth_mac_miim_write(PHY_CTRL, t | MII_CR_RESTART_AUTO_NEG);
}
-static bool
-unprogrammed(const void *t, size_t len)
-{
- int i;
- uint8_t *p = (uint8_t *)t;
- bool all_zeros = true;
- bool all_ones = true;
- for (i = 0; i < len; i++){
- all_zeros &= p[i] == 0x00;
- all_ones &= p[i] == 0xff;
- }
- return all_ones | all_zeros;
-}
-
-//////////////////// MAC Addr Stuff ///////////////////////
-
-static int8_t src_mac_addr_initialized = false;
-static eth_mac_addr_t src_mac_addr = {{
- 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff
- }};
-
-const eth_mac_addr_t *
-ethernet_mac_addr(void)
-{
- if (!src_mac_addr_initialized){ // fetch from eeprom
- src_mac_addr_initialized = true;
-
- // if we're simulating, don't read the EEPROM model, it's REALLY slow
- if (hwconfig_simulation_p())
- return &src_mac_addr;
-
- eth_mac_addr_t tmp;
- bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, &tmp, sizeof(tmp));
- if (!ok || unprogrammed(&tmp, sizeof(tmp))){
- // use the default
- }
- else
- src_mac_addr = tmp;
- }
-
- return &src_mac_addr;
-}
-
-bool
-ethernet_set_mac_addr(const eth_mac_addr_t *t)
-{
- bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, t, sizeof(eth_mac_addr_t));
- if (ok){
- src_mac_addr = *t;
- src_mac_addr_initialized = true;
- //eth_mac_set_addr(t); //this breaks the link
- }
-
- return ok;
-}
-
-//////////////////// IP Addr Stuff ///////////////////////
-
-static int8_t src_ip_addr_initialized = false;
-static struct ip_addr src_ip_addr = {
- (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)
-};
-
-
-const struct ip_addr *get_ip_addr(void)
-{
- if (!src_ip_addr_initialized){ // fetch from eeprom
- src_ip_addr_initialized = true;
-
- // if we're simulating, don't read the EEPROM model, it's REALLY slow
- if (hwconfig_simulation_p())
- return &src_ip_addr;
-
- struct ip_addr tmp;
- bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, &tmp, sizeof(tmp));
- if (!ok || unprogrammed(&tmp, sizeof(tmp))){
- // use the default
- }
- else
- src_ip_addr = tmp;
- }
-
- return &src_ip_addr;
-}
-
-bool set_ip_addr(const struct ip_addr *t){
- bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, t, sizeof(struct ip_addr));
- if (ok){
- src_ip_addr = *t;
- src_ip_addr_initialized = true;
- }
-
- return ok;
-}
-
int
ethernet_check_errors(void)
{
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index bbe9c273f..83b70bddc 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -236,6 +236,11 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{
return bpp/_rx_otw_type.get_sample_size();
}
+static void handle_overflow(std::vector<usrp2_mboard_impl::sptr> &mboards, size_t chan){
+ std::cerr << "O" << std::flush;
+ mboards.at(chan/mboards.size())->handle_overflow();
+}
+
size_t usrp2_impl::recv(
const std::vector<void *> &buffs, size_t num_samps,
rx_metadata_t &metadata, const io_type_t &io_type,
@@ -248,6 +253,7 @@ size_t usrp2_impl::recv(
io_type, _rx_otw_type, //input and output types to convert
_mboards.front()->get_master_clock_freq(), //master clock tick rate
uhd::transport::vrt::if_hdr_unpack_be,
- boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout)
+ boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout),
+ boost::bind(&handle_overflow, _mboards, _1)
);
}
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index e7d8aeef6..e49ac717e 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -167,7 +167,15 @@ void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){
_iface->poke32(U2_REG_TIME64_SECS, boost::uint32_t(time_spec.get_full_secs()));
}
+void usrp2_mboard_impl::handle_overflow(void){
+ _iface->poke32(U2_REG_RX_CTRL_CLEAR_OVERRUN, 1);
+ if (_continuous_streaming){ //re-issue the stream command if already continuous
+ this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
+ }
+}
+
void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){
+ _continuous_streaming = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS;
_iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, dsp_type1::calc_stream_cmd_word(
stream_cmd, _recv_frame_size
));
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 7b1a2b1eb..0a56ec788 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -93,9 +93,12 @@ public:
return _clock_ctrl->get_master_clock_rate();
}
+ void handle_overflow(void);
+
private:
size_t _index;
const size_t _recv_frame_size;
+ bool _continuous_streaming;
//interfaces
usrp2_iface::sptr _iface;
diff --git a/images/Makefile b/images/Makefile
index 57277e787..a2e3d945b 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -119,6 +119,7 @@ $(BUILT_IMAGES_DIR):
mkdir $@
images: $(BUILT_IMAGES_DIR) $(IMAGES_LIST)
+ chmod -x $(BUILT_IMAGES_DIR)/*
clean:
$(RM) -rf $(BUILT_IMAGES_DIR)