aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/e300/e300_io_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/e300/e300_io_impl.cpp')
-rw-r--r--host/lib/usrp/e300/e300_io_impl.cpp48
1 files changed, 40 insertions, 8 deletions
diff --git a/host/lib/usrp/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp
index dcb6f2afe..fa4915ed1 100644
--- a/host/lib/usrp/e300/e300_io_impl.cpp
+++ b/host/lib/usrp/e300/e300_io_impl.cpp
@@ -25,6 +25,7 @@
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/bind.hpp>
#include <uhd/utils/tasks.hpp>
+#include <uhd/utils/log.hpp>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
@@ -226,6 +227,18 @@ void e300_impl::_handle_overflow(
}
}
+static size_t get_rx_flow_control_window(size_t frame_size, size_t sw_buff_size, double fullness_factor)
+{
+ if (fullness_factor < 0.01 || fullness_factor > 1) {
+ throw uhd::value_error("recv_buff_fullness must be between 0.01 and 1 inclusive (1% to 100%)");
+ }
+
+ size_t window_in_pkts = (static_cast<size_t>(sw_buff_size * fullness_factor) / frame_size);
+ if (window_in_pkts == 0) {
+ throw uhd::value_error("recv_buff_size must be larger than the recv_frame_size.");
+ }
+ return window_in_pkts;
+}
static void handle_rx_flowctrl(
const boost::uint32_t sid,
@@ -457,25 +470,38 @@ rx_streamer::sptr e300_impl::get_rx_stream(const uhd::stream_args_t &args_)
id.num_outputs = 1;
my_streamer->set_converter(id);
+ perif.framer->clear();
perif.framer->set_nsamps_per_packet(spp); //seems to be a good place to set this
perif.framer->set_sid((data_sid << 16) | (data_sid >> 16));
perif.framer->setup(args);
perif.ddc->setup(args);
+
+ // flow control setup
+ const size_t frame_size = data_xports.recv->get_recv_frame_size();
+ const size_t num_frames = data_xports.recv->get_num_recv_frames();
+ const size_t fc_window = get_rx_flow_control_window(
+ frame_size,num_frames * frame_size,
+ E300_RX_SW_BUFF_FULLNESS);
+ const size_t fc_handle_window = std::max<size_t>(1, fc_window / E300_RX_FC_REQUEST_FREQ);
+
+ UHD_LOG << "RX Flow Control Window = " << fc_window
+ << ", RX Flow Control Handler Window = "
+ << fc_handle_window << std::endl;
+
+ perif.framer->configure_flow_control(fc_window);
+ boost::shared_ptr<e300_rx_fc_cache_t> fc_cache(new e300_rx_fc_cache_t());
+
my_streamer->set_xport_chan_get_buff(stream_i, boost::bind(
&zero_copy_if::get_recv_buff, data_xports.recv, _1
), true /*flush*/);
my_streamer->set_overflow_handler(stream_i,
- boost::bind(&rx_vita_core_3000::handle_overflow, perif.framer)
+ boost::bind(&e300_impl::_handle_overflow, this, boost::ref(perif),
+ boost::weak_ptr<uhd::rx_streamer>(my_streamer))
);
- //setup flow control
- const size_t fc_window = data_xports.recv->get_num_recv_frames();
- perif.framer->configure_flow_control(fc_window);
- boost::shared_ptr<e300_rx_fc_cache_t> fc_cache(new e300_rx_fc_cache_t());
my_streamer->set_xport_handle_flowctrl(stream_i,
boost::bind(&handle_rx_flowctrl, data_sid, data_xports.send, fc_cache, _1),
- static_cast<size_t>(static_cast<double>(fc_window) * E300_RX_SW_BUFF_FULLNESS),
- true/*init*/);
+ fc_handle_window, true/*init*/);
my_streamer->set_issue_stream_cmd(stream_i,
boost::bind(&rx_vita_core_3000::issue_stream_command, perif.framer, _1)
@@ -564,7 +590,13 @@ tx_streamer::sptr e300_impl::get_tx_stream(const uhd::stream_args_t &args_)
//flow control setup
const size_t fc_window = data_xports.send->get_num_send_frames();
- perif.deframer->configure_flow_control(0/*cycs off*/, fc_window/8/*pkts*/);
+ const size_t fc_handle_window = std::max<size_t>(1, fc_window/E300_TX_FC_RESPONSE_FREQ);
+
+ UHD_LOG << "TX Flow Control Window = " << fc_window
+ << ", TX Flow Control Handler Window = "
+ << fc_handle_window << std::endl;
+
+ perif.deframer->configure_flow_control(0/*cycs off*/, fc_handle_window/*pkts*/);
boost::shared_ptr<e300_tx_fc_cache_t> fc_cache(new e300_tx_fc_cache_t());
fc_cache->stream_channel = stream_i;
fc_cache->device_channel = args.channels[stream_i];