From 6d47818032de6f05aa74d17e50363df292c50aac Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Sun, 17 Jul 2011 23:54:19 -0700
Subject: usrp2: use the err transport for tx/err, and rx xports are recv only

---
 host/lib/usrp/usrp2/fw_common.h    |  6 ++--
 host/lib/usrp/usrp2/io_impl.cpp    | 14 ++++----
 host/lib/usrp/usrp2/usrp2_impl.cpp | 66 +++++++++++++++++++++++---------------
 host/lib/usrp/usrp2/usrp2_impl.hpp |  4 +--
 host/lib/usrp/usrp2/usrp2_regs.hpp |  2 ++
 5 files changed, 54 insertions(+), 38 deletions(-)

(limited to 'host/lib/usrp')

diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 21abc6aed..d47725e1f 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -40,9 +40,9 @@ extern "C" {
 // Dynamic and/or private ports: 49152-65535
 #define USRP2_UDP_CTRL_PORT 49152
 //#define USRP2_UDP_UPDATE_PORT 49154
-#define USRP2_UDP_DSP0_PORT 49156
-#define USRP2_UDP_ERR0_PORT 49157
-#define USRP2_UDP_DSP1_PORT 49158
+#define USRP2_UDP_RX_DSP0_PORT 49156
+#define USRP2_UDP_TX_DSP0_PORT 49157
+#define USRP2_UDP_RX_DSP1_PORT 49158
 
 ////////////////////////////////////////////////////////////////////////
 // I2C addresses
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index 7028e1ff8..7e855d1bd 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -249,9 +249,9 @@ void usrp2_impl::io_init(void){
     //init first so we dont have an access race
     BOOST_FOREACH(const std::string &mb, _mbc.keys()){
         //init the tx xport and flow control monitor
-        _io_impl->tx_xports.push_back(_mbc[mb].dsp_xports.at(0));
+        _io_impl->tx_xports.push_back(_mbc[mb].tx_dsp_xport);
         _io_impl->fc_mons.push_back(flow_control_monitor::sptr(new flow_control_monitor(
-            USRP2_SRAM_BYTES/_mbc[mb].dsp_xports.at(0)->get_send_frame_size()
+            USRP2_SRAM_BYTES/_mbc[mb].tx_dsp_xport->get_send_frame_size()
         )));
     }
 
@@ -261,7 +261,7 @@ void usrp2_impl::io_init(void){
         //spawn a new pirate to plunder the recv booty
         _io_impl->pirate_tasks.push_back(task::make(boost::bind(
             &usrp2_impl::io_impl::recv_pirate_loop, _io_impl.get(),
-            _mbc[mb].err_xports.at(0), index++
+            _mbc[mb].tx_dsp_xport, index++
         )));
     }
 
@@ -273,7 +273,7 @@ void usrp2_impl::io_init(void){
     _io_impl->send_handler.set_max_samples_per_packet(get_max_send_samps_per_packet());
 
     //set the packet threshold to be an entire socket buffer's worth
-    const size_t packets_per_sock_buff = 50e6/_mbc[_mbc.keys().front()].dsp_xports[0]->get_recv_frame_size();
+    const size_t packets_per_sock_buff = 50e6/_mbc[_mbc.keys().front()].rx_dsp_xports[0]->get_recv_frame_size();
     _io_impl->recv_handler.set_alignment_failure_threshold(packets_per_sock_buff);
 }
 
@@ -342,7 +342,7 @@ subdev_spec_t usrp2_impl::update_rx_subdev_spec(const std::string &which_mb, con
         for (size_t dsp = 0; dsp < _mbc[mb].rx_chan_occ; dsp++){
             _mbc[mb].rx_dsps[dsp]->set_nsamps_per_packet(get_max_recv_samps_per_packet()); //seems to be a good place to set this
             _io_impl->recv_handler.set_xport_chan_get_buff(chan++, boost::bind(
-                &zero_copy_if::get_recv_buff, _mbc[mb].dsp_xports[dsp], _1
+                &zero_copy_if::get_recv_buff, _mbc[mb].rx_dsp_xports[dsp], _1
             ));
         }
     }
@@ -398,7 +398,7 @@ size_t usrp2_impl::get_max_send_samps_per_packet(void) const{
         + vrt_send_header_offset_words32*sizeof(boost::uint32_t)
         - sizeof(vrt::if_packet_info_t().cid) //no class id ever used
     ;
-    const size_t bpp = _mbc[_mbc.keys().front()].dsp_xports[0]->get_send_frame_size() - hdr_size;
+    const size_t bpp = _mbc[_mbc.keys().front()].tx_dsp_xport->get_send_frame_size() - hdr_size;
     return bpp/_tx_otw_type.get_sample_size();
 }
 
@@ -423,7 +423,7 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{
         + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer
         - sizeof(vrt::if_packet_info_t().cid) //no class id ever used
     ;
-    const size_t bpp = _mbc[_mbc.keys().front()].dsp_xports[0]->get_recv_frame_size() - hdr_size;
+    const size_t bpp = _mbc[_mbc.keys().front()].rx_dsp_xports[0]->get_recv_frame_size() - hdr_size;
     return bpp/_rx_otw_type.get_sample_size();
 }
 
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index a42d1aae0..058a8f9aa 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -229,7 +229,23 @@ static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &u
 /***********************************************************************
  * Helpers
  **********************************************************************/
-static void init_xport(zero_copy_if::sptr xport){
+static zero_copy_if::sptr make_xport(
+    const std::string &addr,
+    const std::string &port,
+    const device_addr_t &hints,
+    const std::string &filter
+){
+
+    //only copy hints that contain the filter word
+    device_addr_t filtered_hints;
+    BOOST_FOREACH(const std::string &key, hints.keys()){
+        if (key.find(filter) == std::string::npos) continue;
+        filtered_hints[key] = hints[key];
+    }
+
+    //make the transport object with the filtered hints
+    zero_copy_if::sptr xport = udp_zero_copy::make(addr, port, filtered_hints);
+
     //Send a small data packet so the usrp2 knows the udp source port.
     //This setup must happen before further initialization occurs
     //or the async update packets will cause ICMP destination unreachable.
@@ -237,10 +253,11 @@ static void init_xport(zero_copy_if::sptr xport){
         uhd::htonx(boost::uint32_t(0 /* don't care seq num */)),
         uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER))
     };
-
     transport::managed_send_buffer::sptr send_buff = xport->get_send_buff();
     std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));
     send_buff->commit(sizeof(data));
+
+    return xport;
 }
 
 /***********************************************************************
@@ -301,27 +318,6 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
         const std::string addr = device_args_i["addr"];
         const property_tree::path_type mb_path = "/mboards/" + mb;
 
-        ////////////////////////////////////////////////////////////////
-        // construct transports for dsp and async errors
-        ////////////////////////////////////////////////////////////////
-        UHD_LOG << "Making transport for DSP0..." << std::endl;
-        _mbc[mb].dsp_xports.push_back(udp_zero_copy::make(
-            addr, BOOST_STRINGIZE(USRP2_UDP_DSP0_PORT), device_args_i
-        ));
-        init_xport(_mbc[mb].dsp_xports.back());
-
-        UHD_LOG << "Making transport for DSP1..." << std::endl;
-        _mbc[mb].dsp_xports.push_back(udp_zero_copy::make(
-            addr, BOOST_STRINGIZE(USRP2_UDP_DSP1_PORT), device_args_i
-        ));
-        init_xport(_mbc[mb].dsp_xports.back());
-
-        UHD_LOG << "Making transport for ERR0..." << std::endl;
-        _mbc[mb].err_xports.push_back(udp_zero_copy::make(
-            addr, BOOST_STRINGIZE(USRP2_UDP_ERR0_PORT), device_addr_t()
-        ));
-        init_xport(_mbc[mb].err_xports.back());
-
         ////////////////////////////////////////////////////////////////
         // create the iface that controls i2c, spi, uart, and wb
         ////////////////////////////////////////////////////////////////
@@ -350,6 +346,24 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
         //lock the device/motherboard to this process
         _mbc[mb].iface->lock_device(true);
 
+        ////////////////////////////////////////////////////////////////
+        // construct transports for RX and TX DSPs
+        ////////////////////////////////////////////////////////////////
+        UHD_LOG << "Making transport for RX DSP0..." << std::endl;
+        _mbc[mb].rx_dsp_xports.push_back(make_xport(
+            addr, BOOST_STRINGIZE(USRP2_UDP_RX_DSP0_PORT), device_args_i, "recv"
+        ));
+        UHD_LOG << "Making transport for RX DSP1..." << std::endl;
+        _mbc[mb].rx_dsp_xports.push_back(make_xport(
+            addr, BOOST_STRINGIZE(USRP2_UDP_RX_DSP1_PORT), device_args_i, "recv"
+        ));
+        UHD_LOG << "Making transport for TX DSP0..." << std::endl;
+        _mbc[mb].tx_dsp_xport = make_xport(
+            addr, BOOST_STRINGIZE(USRP2_UDP_TX_DSP0_PORT), device_args_i, "send"
+        );
+        //set the filter on the router to take dsp data from this port
+        _mbc[mb].iface->poke32(U2_REG_ROUTER_CTRL_PORTS, USRP2_UDP_TX_DSP0_PORT);
+
         ////////////////////////////////////////////////////////////////
         // setup the mboard eeprom
         ////////////////////////////////////////////////////////////////
@@ -450,8 +464,8 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
                 .subscribe(boost::bind(&rx_dsp_core_200::set_tick_rate, _mbc[mb].rx_dsps[dspno], _1));
             //This is a hack/fix for the lingering packet problem.
             //The dsp core starts streaming briefly... now we flush
-            _mbc[mb].dsp_xports[dspno]->get_recv_buff(0.01).get(); //recv with timeout for lingering
-            _mbc[mb].dsp_xports[dspno]->get_recv_buff(0.01).get(); //recv with timeout for expected
+            _mbc[mb].rx_dsp_xports[dspno]->get_recv_buff(0.01).get(); //recv with timeout for lingering
+            _mbc[mb].rx_dsp_xports[dspno]->get_recv_buff(0.01).get(); //recv with timeout for expected
             property_tree::path_type rx_dsp_path = mb_path / str(boost::format("rx_dsps/%u") % dspno);
             _tree->create<double>(rx_dsp_path / "rate/value")
                 .coerce(boost::bind(&rx_dsp_core_200::set_host_rate, _mbc[mb].rx_dsps[dspno], _1))
@@ -483,7 +497,7 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
 
         //setup dsp flow control
         const double ups_per_sec = device_args_i.cast<double>("ups_per_sec", 20);
-        const size_t send_frame_size = _mbc[mb].dsp_xports.front()->get_send_frame_size();
+        const size_t send_frame_size = _mbc[mb].tx_dsp_xport->get_send_frame_size();
         const double ups_per_fifo = device_args_i.cast<double>("ups_per_fifo", 8.0);
         _mbc[mb].tx_dsp->set_updates(
             (ups_per_sec > 0.0)? size_t(100e6/*approx tick rate*//ups_per_sec) : 0,
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index f2125e094..644eab824 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -99,8 +99,8 @@ private:
         std::vector<rx_dsp_core_200::sptr> rx_dsps;
         tx_dsp_core_200::sptr tx_dsp;
         time64_core_200::sptr time64;
-        std::vector<uhd::transport::zero_copy_if::sptr> dsp_xports;
-        std::vector<uhd::transport::zero_copy_if::sptr> err_xports;
+        std::vector<uhd::transport::zero_copy_if::sptr> rx_dsp_xports;
+        uhd::transport::zero_copy_if::sptr tx_dsp_xport;
         uhd::usrp::dboard_manager::sptr dboard_manager;
         uhd::usrp::dboard_iface::sptr dboard_iface;
         size_t rx_chan_occ, tx_chan_occ;
diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp
index a45a83a21..555e4a3e7 100644
--- a/host/lib/usrp/usrp2/usrp2_regs.hpp
+++ b/host/lib/usrp/usrp2/usrp2_regs.hpp
@@ -54,6 +54,8 @@
 
 #define U2_REG_SR_ADDR(sr) (SETTING_REGS_BASE + (4 * (sr)))
 
+#define U2_REG_ROUTER_CTRL_PORTS U2_REG_SR_ADDR(SR_BUF_POOL) + 8
+
 /////////////////////////////////////////////////
 // SPI Slave Constants
 ////////////////////////////////////////////////
-- 
cgit v1.2.3