From 78be3d548be78ffd871a0563499a6df0bfdf14b4 Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Mon, 23 Feb 2015 13:30:17 -0800 Subject: e300: fc: This should fix the RX flow control. Two issues: - Call the correct overflow handler e300_impl vs rx_vita - Don't lie about buffer sizes and window sizes Signed-off-by: Moritz Fischer --- host/lib/usrp/e300/e300_impl.hpp | 1 + host/lib/usrp/e300/e300_io_impl.cpp | 40 ++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp index a4170ee42..59e0d59ce 100644 --- a/host/lib/usrp/e300/e300_impl.hpp +++ b/host/lib/usrp/e300/e300_impl.hpp @@ -70,6 +70,7 @@ static std::string E300_SERVER_I2C_PORT = "21761"; static std::string E300_SERVER_SENSOR_PORT = "21762"; static const double E300_RX_SW_BUFF_FULLNESS = 0.9; //Buffer should be half full +static const size_t E300_RX_FC_REQUEST_FREQ = 32; // per flow ctrl window // crossbar settings static const boost::uint8_t E300_RADIO_DEST_PREFIX_TX = 0; diff --git a/host/lib/usrp/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp index dcb6f2afe..a1d0a8da1 100644 --- a/host/lib/usrp/e300/e300_io_impl.cpp +++ b/host/lib/usrp/e300/e300_io_impl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -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(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(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 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(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 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(static_cast(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) -- cgit v1.2.3