diff options
Diffstat (limited to 'host/lib/usrp/x300')
-rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 347 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_impl.hpp | 31 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_io_impl.cpp | 16 |
3 files changed, 193 insertions, 201 deletions
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 60be75f2b..d0915d592 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -473,8 +473,10 @@ void x300_impl::mboard_members_t::discover_eth( // Choose the interface based on the index parity if (i % 2 == 0) { conn_iface.type = X300_IFACE_ETH0; + conn_iface.link_rate = loaded_fpga_image == "HG" ? X300_MAX_RATE_1GIGE : X300_MAX_RATE_10GIGE; } else { conn_iface.type = X300_IFACE_ETH1; + conn_iface.link_rate = X300_MAX_RATE_10GIGE; } break; } @@ -492,15 +494,19 @@ void x300_impl::mboard_members_t::discover_eth( if (addr == boost::asio::ip::address_v4( uint32_t(X300_DEFAULT_IP_ETH0_1G)).to_string()) { conn_iface.type = X300_IFACE_ETH0; + conn_iface.link_rate = X300_MAX_RATE_1GIGE; } else if (addr == boost::asio::ip::address_v4( uint32_t(X300_DEFAULT_IP_ETH1_1G)).to_string()) { conn_iface.type = X300_IFACE_ETH1; + conn_iface.link_rate = X300_MAX_RATE_1GIGE; } else if (addr == boost::asio::ip::address_v4( uint32_t(X300_DEFAULT_IP_ETH0_10G)).to_string()) { conn_iface.type = X300_IFACE_ETH0; + conn_iface.link_rate = X300_MAX_RATE_10GIGE; } else if (addr == boost::asio::ip::address_v4( uint32_t(X300_DEFAULT_IP_ETH1_10G)).to_string()) { conn_iface.type = X300_IFACE_ETH1; + conn_iface.link_rate = X300_MAX_RATE_10GIGE; } else { throw uhd::assertion_error(str(boost::format( "X300 Initialization Error: Failed to match address %s with " @@ -624,91 +630,6 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) if (key.find("send") != std::string::npos) mb.send_args[key] = dev_addr[key]; } - if (mb.xport_path == "eth" ) { - /* This is an ETH connection. Figure out what the maximum supported frame - * size is for the transport in the up and down directions. The frame size - * depends on the host PIC's NIC's MTU settings. To determine the frame size, - * we test for support up to an expected "ceiling". If the user - * specified a frame size, we use that frame size as the ceiling. If no - * frame size was specified, we use the maximum UHD frame size. - * - * To optimize performance, the frame size should be greater than or equal - * to the frame size that UHD uses so that frames don't get split across - * multiple transmission units - this is why the limits passed into the - * 'determine_max_frame_size' function are actually frame sizes. */ - frame_size_t req_max_frame_size; - req_max_frame_size.recv_frame_size = (mb.recv_args.has_key("recv_frame_size")) \ - ? boost::lexical_cast<size_t>(mb.recv_args["recv_frame_size"]) \ - : X300_10GE_DATA_FRAME_MAX_SIZE; - req_max_frame_size.send_frame_size = (mb.send_args.has_key("send_frame_size")) \ - ? boost::lexical_cast<size_t>(mb.send_args["send_frame_size"]) \ - : X300_10GE_DATA_FRAME_MAX_SIZE; - - #if defined UHD_PLATFORM_LINUX - const std::string mtu_tool("ip link"); - #elif defined UHD_PLATFORM_WIN32 - const std::string mtu_tool("netsh"); - #else - const std::string mtu_tool("ifconfig"); - #endif - - // Detect the frame size on the path to the USRP - try { - frame_size_t pri_frame_sizes = determine_max_frame_size( - eth_addrs.at(0), req_max_frame_size - ); - - _max_frame_sizes = pri_frame_sizes; - if (eth_addrs.size() > 1) { - frame_size_t sec_frame_sizes = determine_max_frame_size( - eth_addrs.at(1), req_max_frame_size - ); - - // Choose the minimum of the max frame sizes - // to ensure we don't exceed any one of the links' MTU - _max_frame_sizes.recv_frame_size = std::min( - pri_frame_sizes.recv_frame_size, - sec_frame_sizes.recv_frame_size - ); - - _max_frame_sizes.send_frame_size = std::min( - pri_frame_sizes.send_frame_size, - sec_frame_sizes.send_frame_size - ); - } - } catch(std::exception &e) { - UHD_LOGGER_ERROR("X300") << e.what() ; - } - - if ((mb.recv_args.has_key("recv_frame_size")) - && (req_max_frame_size.recv_frame_size > _max_frame_sizes.recv_frame_size)) { - UHD_LOGGER_WARNING("X300") - << boost::format("You requested a receive frame size of (%lu) but your NIC's max frame size is (%lu).") - % req_max_frame_size.recv_frame_size - % _max_frame_sizes.recv_frame_size - << boost::format("Please verify your NIC's MTU setting using '%s' or set the recv_frame_size argument appropriately.") - % mtu_tool - << "UHD will use the auto-detected max frame size for this connection." - ; - } - - if ((mb.recv_args.has_key("send_frame_size")) - && (req_max_frame_size.send_frame_size > _max_frame_sizes.send_frame_size)) { - UHD_LOGGER_WARNING("X300") - << boost::format("You requested a send frame size of (%lu) but your NIC's max frame size is (%lu).") - % req_max_frame_size.send_frame_size - % _max_frame_sizes.send_frame_size - << boost::format("Please verify your NIC's MTU setting using '%s' or set the send_frame_size argument appropriately.") - % mtu_tool - << "UHD will use the auto-detected max frame size for this connection." - ; - } - - _tree->create<size_t>(mb_path / "mtu/recv").set(_max_frame_sizes.recv_frame_size); - _tree->create<size_t>(mb_path / "mtu/send").set(_max_frame_sizes.send_frame_size); - _tree->create<double>(mb_path / "link_max_rate").set(X300_MAX_RATE_10GIGE); - } - //create basic communication UHD_LOGGER_DEBUG("X300") << "Setting up basic communication..."; if (mb.xport_path == "nirio") { @@ -828,11 +749,129 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr) _tree->create<std::string>(mb_path / "codename").set("Yetti"); //////////////////////////////////////////////////////////////////// - // determine routing based on address match + // discover ethernet interfaces, frame sizes, and link rates //////////////////////////////////////////////////////////////////// - if (mb.xport_path != "nirio") { + if (mb.xport_path == "eth" ) { + double link_max_rate = 0.0; + // Discover ethernet interfaces mb.discover_eth(mb_eeprom, eth_addrs); + + /* This is an ETH connection. Figure out what the maximum supported frame + * size is for the transport in the up and down directions. The frame size + * depends on the host PC's NIC's MTU settings. To determine the frame size, + * we test for support up to an expected "ceiling". If the user + * specified a frame size, we use that frame size as the ceiling. If no + * frame size was specified, we use the maximum UHD frame size. + * + * To optimize performance, the frame size should be greater than or equal + * to the frame size that UHD uses so that frames don't get split across + * multiple transmission units - this is why the limits passed into the + * 'determine_max_frame_size' function are actually frame sizes. */ + frame_size_t req_max_frame_size; + req_max_frame_size.recv_frame_size = (mb.recv_args.has_key("recv_frame_size")) \ + ? boost::lexical_cast<size_t>(mb.recv_args["recv_frame_size"]) \ + : X300_DATA_FRAME_MAX_SIZE; + req_max_frame_size.send_frame_size = (mb.send_args.has_key("send_frame_size")) \ + ? boost::lexical_cast<size_t>(mb.send_args["send_frame_size"]) \ + : X300_DATA_FRAME_MAX_SIZE; + + #if defined UHD_PLATFORM_LINUX + const std::string mtu_tool("ip link"); + #elif defined UHD_PLATFORM_WIN32 + const std::string mtu_tool("netsh"); + #else + const std::string mtu_tool("ifconfig"); + #endif + + // Detect the frame size on the path to the USRP + try { + frame_size_t pri_frame_sizes = determine_max_frame_size( + eth_addrs.at(0), req_max_frame_size + ); + + _max_frame_sizes = pri_frame_sizes; + if (eth_addrs.size() > 1) { + frame_size_t sec_frame_sizes = determine_max_frame_size( + eth_addrs.at(1), req_max_frame_size + ); + + // Choose the minimum of the max frame sizes + // to ensure we don't exceed any one of the links' MTU + _max_frame_sizes.recv_frame_size = std::min( + pri_frame_sizes.recv_frame_size, + sec_frame_sizes.recv_frame_size + ); + + _max_frame_sizes.send_frame_size = std::min( + pri_frame_sizes.send_frame_size, + sec_frame_sizes.send_frame_size + ); + } + } catch(std::exception &e) { + UHD_LOGGER_ERROR("X300") << e.what() ; + } + + if ((mb.recv_args.has_key("recv_frame_size")) + && (req_max_frame_size.recv_frame_size > _max_frame_sizes.recv_frame_size)) { + UHD_LOGGER_WARNING("X300") + << boost::format("You requested a receive frame size of (%lu) but your NIC's max frame size is (%lu).") + % req_max_frame_size.recv_frame_size + % _max_frame_sizes.recv_frame_size + + << boost::format("Please verify your NIC's MTU setting using '%s' or set the recv_frame_size argument appropriately.") + % mtu_tool + << "UHD will use the auto-detected max frame size for this connection." + ; + } + + if ((mb.send_args.has_key("send_frame_size")) + && (req_max_frame_size.send_frame_size > _max_frame_sizes.send_frame_size)) { + UHD_LOGGER_WARNING("X300") + << boost::format("You requested a send frame size of (%lu) but your NIC's max frame size is (%lu).") + % req_max_frame_size.send_frame_size + % _max_frame_sizes.send_frame_size + + << boost::format("Please verify your NIC's MTU setting using '%s' or set the send_frame_size argument appropriately.") + % mtu_tool + << "UHD will use the auto-detected max frame size for this connection." + ; + } + + // Check frame sizes + for (auto conn : mb.eth_conns) + { + link_max_rate += conn.link_rate; + + size_t rec_send_frame_size = conn.link_rate == X300_MAX_RATE_1GIGE ? X300_1GE_DATA_FRAME_SEND_SIZE : X300_10GE_DATA_FRAME_SEND_SIZE; + size_t rec_recv_frame_size = conn.link_rate == X300_MAX_RATE_1GIGE ? X300_1GE_DATA_FRAME_RECV_SIZE : X300_10GE_DATA_FRAME_RECV_SIZE; + + if (_max_frame_sizes.send_frame_size < rec_send_frame_size) + { + UHD_LOGGER_WARNING("X300") + << boost::format("For the %s connection, UHD recommends a send frame size of at least %lu for best\nperformance, but your configuration will only allow %lu.") + % conn.addr + % rec_send_frame_size + % _max_frame_sizes.send_frame_size + << "This may negatively impact your maximum achievable sample rate.\nCheck the MTU on the interface and/or the send_frame_size argument." + ; + } + + if (_max_frame_sizes.recv_frame_size < rec_recv_frame_size) + { + UHD_LOGGER_WARNING("X300") + << boost::format("For the %s connection, UHD recommends a receive frame size of at least %lu for best\nperformance, but your configuration will only allow %lu.") + % conn.addr + % rec_recv_frame_size + % _max_frame_sizes.recv_frame_size + << "This may negatively impact your maximum achievable sample rate.\nCheck the MTU on the interface and/or the recv_frame_size argument." + ; + } + } + + _tree->create<size_t>(mb_path / "mtu/recv").set(_max_frame_sizes.recv_frame_size); + _tree->create<size_t>(mb_path / "mtu/send").set(_max_frame_sizes.send_frame_size); + _tree->create<double>(mb_path / "link_max_rate").set(link_max_rate); } //////////////////////////////////////////////////////////////////// @@ -1264,97 +1303,66 @@ uhd::both_xports_t x300_impl::make_transport( xport_type == TX_DATA ? mb.next_tx_src_addr : xport_type == RX_DATA ? mb.next_rx_src_addr : mb.next_src_addr; - std::string interface_addr = mb.eth_conns[next_src_addr].addr; + x300_eth_conn_t conn = mb.eth_conns[next_src_addr]; const uint32_t xbar_src_addr = next_src_addr==0 ? X300_SRC_ADDR0 : X300_SRC_ADDR1; const uint32_t xbar_src_dst = - mb.eth_conns[next_src_addr].type==X300_IFACE_ETH0 ? X300_XB_DST_E0 : X300_XB_DST_E1; - next_src_addr = (next_src_addr + 1) % mb.eth_conns.size(); + conn.type==X300_IFACE_ETH0 ? X300_XB_DST_E0 : X300_XB_DST_E1; + if (xport_type != TX_DATA) next_src_addr = (next_src_addr + 1) % mb.eth_conns.size(); xports.send_sid = this->allocate_sid(mb, address, xbar_src_addr, xbar_src_dst); xports.recv_sid = xports.send_sid.reversed(); - /* Determine what the recommended frame size is for this - * connection type.*/ - size_t eth_data_rec_frame_size = 0; - - fs_path mboard_path = fs_path("/mboards") / mb_index / "link_max_rate"; - - if (mb.loaded_fpga_image == "HG") { - size_t max_link_rate = 0; - if (xbar_src_dst == X300_XB_DST_E0) { - eth_data_rec_frame_size = X300_1GE_DATA_FRAME_MAX_SIZE; - max_link_rate += X300_MAX_RATE_1GIGE; - } else if (xbar_src_dst == X300_XB_DST_E1) { - eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE; - max_link_rate += X300_MAX_RATE_10GIGE; + // Set size and number of frames + size_t system_max_send_frame_size = (size_t) _max_frame_sizes.send_frame_size; + size_t system_max_recv_frame_size = (size_t) _max_frame_sizes.recv_frame_size; + default_buff_args.send_frame_size = std::min(system_max_send_frame_size, X300_ETH_MSG_FRAME_SIZE); + default_buff_args.recv_frame_size = std::min(system_max_recv_frame_size, X300_ETH_MSG_FRAME_SIZE); + default_buff_args.num_send_frames = 1; // never need multiple frames on send + default_buff_args.num_recv_frames = 1; // only need multiple frames with offload thread + default_buff_args.send_buff_size = conn.link_rate / 50; // 20ms + default_buff_args.recv_buff_size = std::max(conn.link_rate / 50, X300_ETH_MSG_NUM_FRAMES * X300_ETH_MSG_FRAME_SIZE); // enough to hold greater of 20ms or number of msg frames + if (xport_type == TX_DATA) + { + size_t default_frame_size = conn.link_rate == X300_MAX_RATE_1GIGE ? X300_1GE_DATA_FRAME_SEND_SIZE : X300_10GE_DATA_FRAME_SEND_SIZE; + default_buff_args.send_frame_size = args.cast<size_t>("send_frame_size", std::min(default_frame_size, system_max_send_frame_size)); + if (default_buff_args.send_frame_size > system_max_send_frame_size) + { + UHD_LOGGER_WARNING("X300") + << boost::format("Requested send_frame_size of %d exceeds the maximum allowed on the %s connection. Using %d.") + % default_buff_args.send_frame_size + % conn.addr + % system_max_send_frame_size + ; + default_buff_args.send_frame_size = system_max_send_frame_size; } - _tree->access<double>(mboard_path).set(max_link_rate); - } else if (mb.loaded_fpga_image == "XG" or mb.loaded_fpga_image == "XA") { - eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE; - size_t max_link_rate = X300_MAX_RATE_10GIGE; - max_link_rate *= mb.eth_conns.size(); - _tree->access<double>(mboard_path).set(max_link_rate); - } else if (mb.loaded_fpga_image == "HA") { - eth_data_rec_frame_size = X300_1GE_DATA_FRAME_MAX_SIZE; - size_t max_link_rate = X300_MAX_RATE_1GIGE; - max_link_rate *= mb.eth_conns.size(); - _tree->access<double>(mboard_path).set(max_link_rate); - } - - if (eth_data_rec_frame_size == 0) { - throw uhd::runtime_error("Unable to determine ETH link type."); } + else if (xport_type == RX_DATA) + { + size_t default_frame_size = conn.link_rate == X300_MAX_RATE_1GIGE ? X300_1GE_DATA_FRAME_RECV_SIZE : X300_10GE_DATA_FRAME_RECV_SIZE; + default_buff_args.recv_frame_size = args.cast<size_t>("recv_frame_size", std::min(default_frame_size, system_max_recv_frame_size)); + if (default_buff_args.recv_frame_size > system_max_recv_frame_size) + { + UHD_LOGGER_WARNING("X300") + << boost::format("Requested recv_frame_size of %d exceeds the maximum allowed on the %s connection. Using %d.") + % default_buff_args.recv_frame_size + % conn.addr + % system_max_recv_frame_size + ; + default_buff_args.recv_frame_size = system_max_recv_frame_size; + } + // set default buffering for data + default_buff_args.recv_buff_size = conn.link_rate / 10; // 100ms + default_buff_args.num_recv_frames = 2; // set some buffers so the offload thread actually offloads the socket I/O - /* Print a warning if the system's max available frame size is less than the most optimal - * frame size for this type of connection. */ - if (_max_frame_sizes.send_frame_size < eth_data_rec_frame_size) { - UHD_LOGGER_WARNING("X300") - << boost::format("For this connection, UHD recommends a send frame size of at least %lu for best\nperformance, but your system's MTU will only allow %lu.") - % eth_data_rec_frame_size - % _max_frame_sizes.send_frame_size - << "This may negatively impact your maximum achievable sample rate." - ; + // set buffering for flow control messages + default_buff_args.num_send_frames = 1; } - if (_max_frame_sizes.recv_frame_size < eth_data_rec_frame_size) { - UHD_LOGGER_WARNING("X300") - << boost::format("For this connection, UHD recommends a receive frame size of at least %lu for best\nperformance, but your system's MTU will only allow %lu.") - % eth_data_rec_frame_size - % _max_frame_sizes.recv_frame_size - << "This may negatively impact your maximum achievable sample rate." - ; - } - - size_t system_max_send_frame_size = (size_t) _max_frame_sizes.send_frame_size; - size_t system_max_recv_frame_size = (size_t) _max_frame_sizes.recv_frame_size; - - // Make sure frame sizes do not exceed the max available value supported by UHD - default_buff_args.send_frame_size = - (xport_type == TX_DATA) - ? std::min(system_max_send_frame_size, X300_10GE_DATA_FRAME_MAX_SIZE) - : std::min(system_max_send_frame_size, X300_ETH_MSG_FRAME_SIZE); - - default_buff_args.recv_frame_size = - (xport_type == RX_DATA) - ? std::min(system_max_recv_frame_size, X300_10GE_DATA_FRAME_MAX_SIZE) - : std::min(system_max_recv_frame_size, X300_ETH_MSG_FRAME_SIZE); - - default_buff_args.num_send_frames = - (xport_type == TX_DATA) - ? X300_ETH_DATA_NUM_FRAMES - : X300_ETH_MSG_NUM_FRAMES; - - default_buff_args.num_recv_frames = - (xport_type == RX_DATA) - ? X300_ETH_DATA_NUM_FRAMES - : X300_ETH_MSG_NUM_FRAMES; - //make a new transport - fpga has no idea how to talk to us on this yet udp_zero_copy::buff_params buff_params; - xports.recv = udp_zero_copy::make( - interface_addr, + conn.addr, BOOST_STRINGIZE(X300_VITA_UDP_PORT), default_buff_args, buff_params, @@ -1365,12 +1373,12 @@ uhd::both_xports_t x300_impl::make_transport( if (xport_type == RX_DATA) { xports.recv = zero_copy_recv_offload::make( xports.recv, - X300_THREAD_BUFFER_TIMEOUT + X300_RECV_OFFLOAD_BUFFER_TIMEOUT ); } xports.send = xports.recv; - //For the UDP transport the buffer size if the size of the socket buffer + //For the UDP transport the buffer size is the size of the socket buffer //in the kernel xports.recv_buff_size = buff_params.recv_buff_size; xports.send_buff_size = buff_params.send_buff_size; @@ -1381,9 +1389,8 @@ uhd::both_xports_t x300_impl::make_transport( //send a mini packet with SID into the ZPU //ZPU will reprogram the ethernet framer - UHD_LOGGER_TRACE("X300") - << "programming packet for new xport on " - << interface_addr << " sid " << xports.send_sid; + UHD_LOGGER_DEBUG("X300") << "programming packet for new xport on " + << conn.addr << " sid " << xports.send_sid ; //YES, get a __send__ buffer from the __recv__ socket //-- this is the only way to program the framer for recv: managed_send_buffer::sptr buff = xports.recv->get_send_buff(); @@ -1691,9 +1698,9 @@ x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &a //Reducing range of (min,max) by setting max value to 10gig max_frame_size as larger sizes are not supported size_t min_recv_frame_size = sizeof(x300_mtu_t); - size_t max_recv_frame_size = std::min(user_frame_size.recv_frame_size, X300_10GE_DATA_FRAME_MAX_SIZE) & size_t(~3); + size_t max_recv_frame_size = std::min(user_frame_size.recv_frame_size, X300_DATA_FRAME_MAX_SIZE) & size_t(~3); size_t min_send_frame_size = sizeof(x300_mtu_t); - size_t max_send_frame_size = std::min(user_frame_size.send_frame_size, X300_10GE_DATA_FRAME_MAX_SIZE) & size_t(~3); + size_t max_send_frame_size = std::min(user_frame_size.send_frame_size, X300_DATA_FRAME_MAX_SIZE) & size_t(~3); UHD_LOGGER_DEBUG("X300") << "Determining maximum frame size... "; while (min_recv_frame_size < max_recv_frame_size) diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index e67242aa3..dfe038107 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -39,9 +39,6 @@ static const std::string X300_DEFAULT_CLOCK_SOURCE = "internal"; static const double X300_DEFAULT_TICK_RATE = 200e6; //Hz static const double X300_BUS_CLOCK_RATE = 187.5e6; //Hz -static const size_t X300_RX_SW_BUFF_SIZE_ETH = 0x2000000;//32MiB For an ~8k frame size any size >32MiB is just wasted buffer space -static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib - //The FIFO closest to the DMA controller is 1023 elements deep for RX and 1029 elements deep for TX //where an element is 8 bytes. The buffers (number of frames * frame size) must be aligned to the //memory page size. For the control, we are getting lucky because 64 frames * 256 bytes each aligns @@ -50,22 +47,25 @@ static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib static const size_t X300_PCIE_RX_DATA_FRAME_SIZE = 4096; //bytes static const size_t X300_PCIE_RX_DATA_NUM_FRAMES = 4096; static const size_t X300_PCIE_TX_DATA_FRAME_SIZE = 4096; //bytes -static const size_t X300_PCIE_TX_DATA_NUM_FRAMES = 4096; +static const size_t X300_PCIE_TX_DATA_NUM_FRAMES = 4096; static const size_t X300_PCIE_MSG_FRAME_SIZE = 256; //bytes static const size_t X300_PCIE_MSG_NUM_FRAMES = 64; static const size_t X300_PCIE_MAX_CHANNELS = 6; static const size_t X300_PCIE_MAX_MUXED_CTRL_XPORTS = 32; static const size_t X300_PCIE_MAX_MUXED_ASYNC_XPORTS = 4; -//Reduced to 4000 to make sure flow control packets are not blocked for too long at high rates -static const size_t X300_10GE_DATA_FRAME_MAX_SIZE = 4000; // CHDR packet size in bytes -static const size_t X300_1GE_DATA_FRAME_MAX_SIZE = 1472; // CHDR packet size in bytes +static const size_t X300_DATA_FRAME_MAX_SIZE = 8000; // CHDR packet size in bytes + +// Ethernet frame sizes +static const size_t X300_10GE_DATA_FRAME_SEND_SIZE = 4000; // Reduced to make sure flow control packets are not blocked for too long at high rates +static const size_t X300_10GE_DATA_FRAME_RECV_SIZE = 8000; +static const size_t X300_1GE_DATA_FRAME_SEND_SIZE = 1472; +static const size_t X300_1GE_DATA_FRAME_RECV_SIZE = 1472; static const size_t X300_ETH_MSG_FRAME_SIZE = uhd::transport::udp_simple::mtu; //bytes +static const size_t X300_ETH_MSG_NUM_FRAMES = 64; -static const double X300_THREAD_BUFFER_TIMEOUT = 0.1; // Time in seconds +static const double X300_RECV_OFFLOAD_BUFFER_TIMEOUT = 0.1; //seconds -static const size_t X300_ETH_MSG_NUM_FRAMES = 64; -static const size_t X300_ETH_DATA_NUM_FRAMES = 32; static const double X300_DEFAULT_SYSREF_RATE = 10e6; // Limit the number of initialization threads @@ -74,12 +74,12 @@ static const size_t X300_MAX_INIT_THREADS = 10; static const size_t X300_MAX_RATE_PCIE = 800000000; // bytes/s static const size_t X300_MAX_RATE_10GIGE = (size_t)( // bytes/s 10e9 / 8 * // wire speed multiplied by percentage of packets that is sample data - ( float(X300_10GE_DATA_FRAME_MAX_SIZE - uhd::usrp::DEVICE3_TX_MAX_HDR_LEN) / - float(X300_10GE_DATA_FRAME_MAX_SIZE + 8 /* UDP header */ + 20 /* Ethernet header length */ ))); + ( float(X300_DATA_FRAME_MAX_SIZE - uhd::usrp::DEVICE3_TX_MAX_HDR_LEN) / + float(X300_DATA_FRAME_MAX_SIZE + 8 /* UDP header */ + 20 /* Ethernet header length */ ))); static const size_t X300_MAX_RATE_1GIGE = (size_t)( // bytes/s - 10e9 / 8 * // wire speed multiplied by percentage of packets that is sample data - ( float(X300_1GE_DATA_FRAME_MAX_SIZE - uhd::usrp::DEVICE3_TX_MAX_HDR_LEN) / - float(X300_1GE_DATA_FRAME_MAX_SIZE + 8 /* UDP header */ + 20 /* Ethernet header length */ ))); + 1e9 / 8 * // wire speed multiplied by percentage of packets that is sample data + ( float(X300_DATA_FRAME_MAX_SIZE - uhd::usrp::DEVICE3_TX_MAX_HDR_LEN) / + float(X300_DATA_FRAME_MAX_SIZE + 8 /* UDP header */ + 20 /* Ethernet header length */ ))); #define X300_RADIO_DEST_PREFIX_TX 0 @@ -106,6 +106,7 @@ struct x300_eth_conn_t { std::string addr; x300_eth_iface_t type; + size_t link_rate; }; diff --git a/host/lib/usrp/x300/x300_io_impl.cpp b/host/lib/usrp/x300/x300_io_impl.cpp index af5aa7c9e..d833b3715 100644 --- a/host/lib/usrp/x300/x300_io_impl.cpp +++ b/host/lib/usrp/x300/x300_io_impl.cpp @@ -17,22 +17,6 @@ using namespace uhd::usrp; device_addr_t x300_impl::get_rx_hints(size_t mb_index) { device_addr_t rx_hints = _mb[mb_index].recv_args; - // (default to a large recv buff) - if (not rx_hints.has_key("recv_buff_size")) - { - if (_mb[mb_index].xport_path != "nirio") { - //For the ethernet transport, the buffer has to be set before creating - //the transport because it is independent of the frame size and # frames - //For nirio, the buffer size is not configurable by the user - #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) - //limit buffer resize on macos or it will error - rx_hints["recv_buff_size"] = std::to_string(X300_RX_SW_BUFF_SIZE_ETH_MACOS); - #elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) - //set to half-a-second of buffering at max rate - rx_hints["recv_buff_size"] = std::to_string(X300_RX_SW_BUFF_SIZE_ETH); - #endif - } - } return rx_hints; } |