aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_eth_mgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/x300/x300_eth_mgr.cpp')
-rw-r--r--host/lib/usrp/x300/x300_eth_mgr.cpp152
1 files changed, 54 insertions, 98 deletions
diff --git a/host/lib/usrp/x300/x300_eth_mgr.cpp b/host/lib/usrp/x300/x300_eth_mgr.cpp
index 7177032c6..fd826e484 100644
--- a/host/lib/usrp/x300/x300_eth_mgr.cpp
+++ b/host/lib/usrp/x300/x300_eth_mgr.cpp
@@ -7,6 +7,7 @@
#include "x300_eth_mgr.hpp"
#include "x300_claim.hpp"
#include "x300_defaults.hpp"
+#include "x300_device_args.hpp"
#include "x300_fw_common.h"
#include "x300_mb_eeprom.hpp"
#include "x300_mb_eeprom_iface.hpp"
@@ -17,16 +18,17 @@
#include <uhd/transport/udp_constants.hpp>
#include <uhd/transport/udp_simple.hpp>
#include <uhd/transport/udp_zero_copy.hpp>
+#include <uhd/utils/algorithm.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhdlib/rfnoc/device_id.hpp>
#include <uhdlib/rfnoc/rfnoc_common.hpp>
#include <uhdlib/transport/udp_boost_asio_link.hpp>
#include <uhdlib/transport/udp_common.hpp>
#include <uhdlib/usrp/cores/i2c_core_100_wb32.hpp>
-//#ifdef HAVE_DPDK
-//# include <uhdlib/transport/dpdk_simple.hpp>
-//# include <uhdlib/transport/dpdk_zero_copy.hpp>
-//#endif
+#ifdef HAVE_DPDK
+# include <uhdlib/transport/dpdk_simple.hpp>
+# include <uhdlib/transport/udp_dpdk_link.hpp>
+#endif
#include <boost/asio.hpp>
#include <string>
@@ -69,42 +71,41 @@ constexpr size_t MAX_RATE_1GIGE = (size_t)( // bytes/s
/******************************************************************************
* Static Methods
*****************************************************************************/
-eth_manager::udp_simple_factory_t eth_manager::x300_get_udp_factory(
- const device_addr_t& args)
+eth_manager::udp_simple_factory_t eth_manager::x300_get_udp_factory(const bool use_dpdk)
{
udp_simple_factory_t udp_make_connected = udp_simple::make_connected;
- if (args.has_key("use_dpdk")) {
-//#ifdef HAVE_DPDK
-// udp_make_connected = [](const std::string& addr, const std::string& port) {
-// auto& ctx = uhd::transport::uhd_dpdk_ctx::get();
-// return dpdk_simple::make_connected(ctx, addr, port);
-// };
-//#else
+ if (use_dpdk) {
+#ifdef HAVE_DPDK
+ udp_make_connected = [](const std::string& addr, const std::string& port) {
+ return dpdk_simple::make_connected(addr, port);
+ };
+#else
UHD_LOG_WARNING(
"DPDK", "Detected use_dpdk argument, but DPDK support not built in.");
-//#endif
+#endif
}
return udp_make_connected;
}
device_addrs_t eth_manager::find(const device_addr_t& hint)
{
+ x300_device_args_t hint_args;
+ hint_args.parse(hint);
+
udp_simple_factory_t udp_make_broadcast = udp_simple::make_broadcast;
- udp_simple_factory_t udp_make_connected = x300_get_udp_factory(hint);
+ udp_simple_factory_t udp_make_connected =
+ x300_get_udp_factory(hint_args.get_use_dpdk());
#ifdef HAVE_DPDK
- if (hint.has_key("use_dpdk")) {
-// auto& dpdk_ctx = uhd::transport::uhd_dpdk_ctx::get();
-// if (not dpdk_ctx.is_init_done()) {
-// dpdk_ctx.init(hint);
-// }
-// udp_make_broadcast = [](const std::string& addr, const std::string& port) {
-// auto& ctx = uhd::transport::uhd_dpdk_ctx::get();
-// return dpdk_simple::make_broadcast(ctx, addr, port);
-// };
+ if (hint_args.get_use_dpdk()) {
+ auto dpdk_ctx = uhd::transport::dpdk::dpdk_ctx::get();
+ if (not dpdk_ctx->is_init_done()) {
+ dpdk_ctx->init(hint);
+ }
+ udp_make_broadcast = dpdk_simple::make_broadcast;
}
#endif
- udp_simple::sptr comm =
- udp_make_broadcast(hint["addr"], BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT));
+ udp_simple::sptr comm = udp_make_broadcast(
+ hint_args.get_first_addr(), BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT));
// load request struct
x300_fw_comms_t request = x300_fw_comms_t();
@@ -177,9 +178,8 @@ device_addrs_t eth_manager::find(const device_addr_t& hint)
/******************************************************************************
* Structors
*****************************************************************************/
-eth_manager::eth_manager(const x300_device_args_t& args,
- uhd::property_tree::sptr tree,
- const uhd::fs_path& root_path)
+eth_manager::eth_manager(
+ const x300_device_args_t& args, uhd::property_tree::sptr, const uhd::fs_path&)
: _args(args)
{
UHD_ASSERT_THROW(!args.get_first_addr().empty());
@@ -201,10 +201,7 @@ eth_manager::eth_manager(const x300_device_args_t& args,
_local_device_ids.push_back(device_id);
eth_conns[device_id] = init;
- _x300_make_udp_connected = x300_get_udp_factory(dev_addr);
-
- tree->create<double>(root_path / "link_max_rate").set(10e9);
- _tree = tree->subtree(root_path);
+ _x300_make_udp_connected = x300_get_udp_factory(args.get_use_dpdk());
}
both_links_t eth_manager::get_links(link_type_t link_type,
@@ -213,12 +210,13 @@ both_links_t eth_manager::get_links(link_type_t link_type,
const sep_id_t& /*remote_epid*/,
const device_addr_t& link_args)
{
- if (std::find(_local_device_ids.cbegin(), _local_device_ids.cend(), local_device_id)
- == _local_device_ids.cend()) {
- throw uhd::runtime_error(
- std::string("[X300] Cannot create Ethernet link through local device ID ")
+ if (!uhd::has(_local_device_ids, local_device_id)) {
+ const std::string err_msg =
+ std::string("Cannot create Ethernet link through local device ID ")
+ std::to_string(local_device_id)
- + ", no such device associated with this motherboard!");
+ + ", no such device associated with this motherboard!";
+ UHD_LOG_ERROR("X300", err_msg);
+ throw uhd::runtime_error(err_msg);
}
// FIXME: We now need to properly associate local_device_id with the right
// entry in eth_conn. We should probably do the load balancing elsewhere,
@@ -236,56 +234,6 @@ both_links_t eth_manager::get_links(link_type_t link_type,
default_buff_args.send_frame_size = std::min(send_mtu, ETH_MSG_FRAME_SIZE);
default_buff_args.recv_frame_size = std::min(recv_mtu, ETH_MSG_FRAME_SIZE);
- if (_args.get_use_dpdk()) {
-//#ifdef HAVE_DPDK
- // auto& dpdk_ctx = uhd::transport::uhd_dpdk_ctx::get();
-
-// default_buff_args.num_recv_frames = ETH_MSG_NUM_FRAMES;
-// default_buff_args.num_send_frames = ETH_MSG_NUM_FRAMES;
-// if (link_type == link_type_t::CTRL) {
-//// Increasing number of recv frames here because ctrl_iface uses it
-//// to determine how many control packets can be in flight before it
-//// must wait for an ACK
-// default_buff_args.num_recv_frames =
-// uhd::rfnoc::CMD_FIFO_SIZE / uhd::rfnoc::MAX_CMD_PKT_SIZE;
-//} else if (xport_type == uhd::transport::link_type_t::TX_DATA) {
-// size_t default_frame_size = conn.link_rate == MAX_RATE_1GIGE
-//? GE_DATA_FRAME_SEND_SIZE
-//: XGE_DATA_FRAME_SEND_SIZE;
-// default_buff_args.send_frame_size = args.cast<size_t>(
-//"send_frame_size", std::min(default_frame_size, send_mtu));
-// default_buff_args.num_send_frames =
-// args.cast<size_t>("num_send_frames", default_buff_args.num_send_frames);
-// default_buff_args.send_buff_size = args.cast<size_t>("send_buff_size", 0);
-//} else if (xport_type == uhd::transport::link_type_t::RX_DATA) {
-// size_t default_frame_size = conn.link_rate == MAX_RATE_1GIGE
-//? GE_DATA_FRAME_RECV_SIZE
-//: XGE_DATA_FRAME_RECV_SIZE;
-// default_buff_args.recv_frame_size = args.cast<size_t>(
-//"recv_frame_size", std::min(default_frame_size, recv_mtu));
-// default_buff_args.num_recv_frames =
-// args.cast<size_t>("num_recv_frames", default_buff_args.num_recv_frames);
-// default_buff_args.recv_buff_size = args.cast<size_t>("recv_buff_size", 0);
-//}
-
-// int dpdk_port_id = dpdk_ctx.get_route(conn.addr);
-// if (dpdk_port_id < 0) {
-// throw uhd::runtime_error(
-//"Could not find a DPDK port with route to " + conn.addr);
-//}
-// auto recv = transport::dpdk_zero_copy::make(dpdk_ctx,
-//(const unsigned int)dpdk_port_id,
-// conn.addr,
-// BOOST_STRINGIZE(X300_VITA_UDP_PORT),
-//"0",
-// default_buff_args,
-// uhd::device_addr_t());
-
-//#else
- UHD_LOG_WARNING("X300", "Cannot create DPDK transport, falling back to UDP");
-//#endif
- }
-
// Buffering is done in the socket buffers, so size them relative to
// the link rate
link_params_t default_link_params;
@@ -315,7 +263,19 @@ both_links_t eth_manager::get_links(link_type_t link_type,
link_params.num_send_frames = std::max(uhd::rfnoc::MIN_NUM_FRAMES, link_params.num_send_frames);
link_params.num_recv_frames = std::max(uhd::rfnoc::MIN_NUM_FRAMES, link_params.num_recv_frames);
+ // Dummy variables for populating the return tuple
size_t recv_buff_size, send_buff_size;
+ if (_args.get_use_dpdk()) {
+#ifdef HAVE_DPDK
+ auto link = uhd::transport::udp_dpdk_link::make(
+ conn.addr, BOOST_STRINGIZE(X300_VITA_UDP_PORT), link_params);
+ return std::make_tuple(link, send_buff_size, link, recv_buff_size, true);
+#else
+ UHD_LOG_WARNING("X300", "Cannot create DPDK transport, falling back to UDP");
+#endif
+ }
+
+ // No DPDK, then return regular/kernel UDP
auto link = uhd::transport::udp_boost_asio_link::make(conn.addr,
BOOST_STRINGIZE(X300_VITA_UDP_PORT),
link_params,
@@ -333,11 +293,10 @@ wb_iface::sptr eth_manager::get_ctrl_iface()
get_pri_eth().addr, BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)));
}
+// - Populates _max_frame_sizes
void eth_manager::init_link(
const mboard_eeprom_t& mb_eeprom, const std::string& loaded_fpga_image)
{
- double link_max_rate = 0.0;
-
// Discover ethernet interfaces on the device
discover_eth(mb_eeprom, loaded_fpga_image);
@@ -392,6 +351,8 @@ void eth_manager::init_link(
UHD_LOGGER_ERROR("X300") << e.what();
}
+ // Check actual frame sizes against user-requested frame sizes, and print
+ // warnings if they don't match
if ((recv_args.has_key("recv_frame_size"))
&& (req_max_frame_size.recv_frame_size > _max_frame_sizes.recv_frame_size)) {
UHD_LOGGER_WARNING("X300")
@@ -416,11 +377,10 @@ void eth_manager::init_link(
<< "UHD will use the auto-detected max frame size for this connection.";
}
- // Check frame sizes
+ // Check actual frame sizes against detected frame sizes, and print
+ // warnings if they don't match
for (auto conn_pair : eth_conns) {
auto conn = conn_pair.second;
- link_max_rate += conn.link_rate;
-
size_t rec_send_frame_size = conn.link_rate == MAX_RATE_1GIGE
? GE_DATA_FRAME_SEND_SIZE
: XGE_DATA_FRAME_SEND_SIZE;
@@ -452,10 +412,6 @@ void eth_manager::init_link(
"argument.";
}
}
-
- _tree->create<size_t>("mtu/recv").set(_max_frame_sizes.recv_frame_size);
- _tree->create<size_t>("mtu/send").set(_max_frame_sizes.send_frame_size);
- _tree->access<double>("link_max_rate").set(link_max_rate);
}
size_t eth_manager::get_mtu(uhd::direction_t dir)
@@ -468,7 +424,7 @@ size_t eth_manager::get_mtu(uhd::direction_t dir)
void eth_manager::discover_eth(
const mboard_eeprom_t mb_eeprom, const std::string& loaded_fpga_image)
{
- udp_simple_factory_t udp_make_connected = x300_get_udp_factory(_args.get_orig_args());
+ udp_simple_factory_t udp_make_connected = x300_get_udp_factory(_args.get_use_dpdk());
// Load all valid, non-duplicate IP addrs
std::vector<std::string> ip_addrs{_args.get_first_addr()};
if (not _args.get_second_addr().empty()