aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/lib/include/uhdlib/rfnoc/chdr_types.hpp33
-rw-r--r--host/lib/rfnoc/chdr_types.cpp47
-rw-r--r--host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp7
-rw-r--r--host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp6
-rw-r--r--host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp13
-rw-r--r--host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp6
-rw-r--r--host/lib/usrp/mpmd/mpmd_mb_iface.cpp2
-rw-r--r--host/tests/rfnoc_chdr_test.cpp106
8 files changed, 192 insertions, 28 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp
index 6e650507f..3eea40850 100644
--- a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp
+++ b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp
@@ -678,6 +678,12 @@ public:
return _op_payload;
}
+ //! Comparison operator (==)
+ inline bool operator==(const mgmt_op_t& rhs) const
+ {
+ return (_op_code == rhs._op_code) && (_op_payload == rhs._op_payload);
+ }
+
private:
const op_code_t _op_code;
const payload_t _op_payload;
@@ -712,12 +718,24 @@ public:
}
//! Serialize the payload to a uint64_t buffer
+ // The RFNoC Specification section 2.2.6 specifies that for chdr widths
+ // greater than 64, all MSBs are 0, so we pad out the hop based on the width
size_t serialize(std::vector<uint64_t>& target,
- const std::function<uint64_t(uint64_t)>& conv_byte_order) const;
+ const std::function<uint64_t(uint64_t)>& conv_byte_order,
+ const size_t padding_size) const;
//! Deserialize the payload from a uint64_t buffer
+ // The RFNoC Specification section 2.2.6 specifies that for chdr widths
+ // greater than 64, all MSBs are 0, so we remove padding based on the width
void deserialize(std::list<uint64_t>& src,
- const std::function<uint64_t(uint64_t)>& conv_byte_order);
+ const std::function<uint64_t(uint64_t)>& conv_byte_order,
+ const size_t padding_size);
+
+ //! Comparison operator (==)
+ inline bool operator==(const mgmt_hop_t& rhs) const
+ {
+ return _ops == rhs._ops;
+ }
private:
std::vector<mgmt_op_t> _ops;
@@ -737,9 +755,10 @@ public:
inline void set_header(sep_id_t src_epid, uint16_t protover, chdr_w_t chdr_w)
{
- _src_epid = src_epid;
- _chdr_w = chdr_w;
- _protover = protover;
+ _src_epid = src_epid;
+ _chdr_w = chdr_w;
+ _protover = protover;
+ _padding_size = (chdr_w_to_bits(_chdr_w) / 64) - 1;
}
//! Add a management hop to this transaction
@@ -814,11 +833,15 @@ public:
return _src_epid;
}
+ //! Comparison operator (==)
+ bool operator==(const mgmt_payload& rhs) const;
+
private:
sep_id_t _src_epid = 0;
uint16_t _protover = 0;
chdr_w_t _chdr_w = CHDR_W_64;
std::vector<mgmt_hop_t> _hops;
+ size_t _padding_size = 0;
};
}}} // namespace uhd::rfnoc::chdr
diff --git a/host/lib/rfnoc/chdr_types.cpp b/host/lib/rfnoc/chdr_types.cpp
index 0e30dca7e..cb4642f3a 100644
--- a/host/lib/rfnoc/chdr_types.cpp
+++ b/host/lib/rfnoc/chdr_types.cpp
@@ -330,20 +330,25 @@ const std::string strc_payload::to_string() const
//! Serialize this hop into a list of 64-bit words
size_t mgmt_hop_t::serialize(std::vector<uint64_t>& target,
- const std::function<uint64_t(uint64_t)>& conv_byte_order) const
+ const std::function<uint64_t(uint64_t)>& conv_byte_order,
+ const size_t padding_size) const
{
for (size_t i = 0; i < get_num_ops(); i++) {
target.push_back(
conv_byte_order((static_cast<uint64_t>(_ops.at(i).get_op_payload()) << 16)
| (static_cast<uint64_t>(_ops.at(i).get_op_code()) << 8)
| (static_cast<uint64_t>(get_num_ops() - i - 1) << 0)));
+ for (size_t j = 0; j < padding_size; j++) {
+ target.push_back(uint64_t(0));
+ }
}
return get_num_ops();
}
//! Deserialize this hop into from list of 64-bit words
-void mgmt_hop_t::deserialize(
- std::list<uint64_t>& src, const std::function<uint64_t(uint64_t)>& conv_byte_order)
+void mgmt_hop_t::deserialize(std::list<uint64_t>& src,
+ const std::function<uint64_t(uint64_t)>& conv_byte_order,
+ const size_t padding_size)
{
_ops.clear();
size_t ops_remaining = 0;
@@ -357,6 +362,10 @@ void mgmt_hop_t::deserialize(
static_cast<uint64_t>((op_word >> 16)));
_ops.push_back(op);
src.pop_front();
+ for (size_t i = 0; i < padding_size; i++) {
+ src.pop_front();
+ }
+
} while (ops_remaining > 0);
}
@@ -381,9 +390,15 @@ size_t mgmt_payload::serialize(uint64_t* buff,
| (static_cast<uint64_t>(static_cast<uint8_t>(_chdr_w) & 0x7) << 45)
| (static_cast<uint64_t>(get_num_hops() & 0x3FF) << 16)
| (static_cast<uint64_t>(_src_epid) << 0)));
+ // According to the RFNoC specification section 2.2.6, the MSBs are 0 for
+ // all widths greater than 64. This logic adds the padding.
+ for (size_t i = 0; i < _padding_size; i++) {
+ target.push_back(uint64_t(0));
+ }
+
// Insert data from each hop
for (const auto& hop : _hops) {
- hop.serialize(target, conv_byte_order);
+ hop.serialize(target, conv_byte_order, _padding_size);
}
UHD_ASSERT_THROW(target.size() <= max_size_bytes);
@@ -401,21 +416,27 @@ void mgmt_payload::deserialize(const uint64_t* buff,
// We use a list and copy just for ease of implementation
// These transactions are not performance critical
- std::list<uint64_t> src_list(buff, buff + num_elems);
+ std::list<uint64_t> src_list(buff, buff + (num_elems * (_padding_size + 1)));
_hops.clear();
// Deframe the header
uint64_t hdr = conv_byte_order(src_list.front());
_hops.resize(static_cast<size_t>((hdr >> 16) & 0x3FF));
- _src_epid = static_cast<sep_id_t>(hdr & 0xFFFF);
- _chdr_w = static_cast<chdr_w_t>((hdr >> 45) & 0x7);
- _protover = static_cast<uint16_t>((hdr >> 48) & 0xFFFF);
+ _src_epid = static_cast<sep_id_t>(hdr & 0xFFFF);
+ _chdr_w = static_cast<chdr_w_t>((hdr >> 45) & 0x7);
+ _protover = static_cast<uint16_t>((hdr >> 48) & 0xFFFF);
+ _padding_size = (chdr_w_to_bits(_chdr_w) / 64) - 1;
src_list.pop_front();
+ // According to the RFNoC specification section 2.2.6, the MSBs are 0 for
+ // all widths greater than 64. This logic removes the padding.
+ for (size_t i = 0; i < _padding_size; i++) {
+ src_list.pop_front();
+ }
// Populate all hops
for (size_t i = 0; i < get_num_hops(); i++) {
- _hops[i].deserialize(src_list, conv_byte_order);
+ _hops[i].deserialize(src_list, conv_byte_order, _padding_size);
}
}
@@ -425,3 +446,11 @@ const std::string mgmt_payload::to_string() const
"mgmt_payload{src_epid:%lu, chdr_w:%d, protover:0x%x, num_hops:%lu}\n")
% _src_epid % int(_chdr_w) % _protover % _hops.size());
}
+
+
+bool mgmt_payload::operator==(const mgmt_payload& rhs) const
+{
+ return (_src_epid == rhs._src_epid) && (_protover == rhs._protover)
+ && (_chdr_w == rhs._chdr_w) && (_hops == rhs._hops)
+ && (_padding_size == rhs._padding_size);
+}
diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp
index b4a0dfd32..bdf088025 100644
--- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp
+++ b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.cpp
@@ -26,9 +26,6 @@ using namespace uhd;
using namespace uhd::transport;
using namespace uhd::mpmd::xport;
-const uhd::rfnoc::chdr::chdr_packet_factory mpmd_link_if_ctrl_udp::_pkt_factory(
- uhd::rfnoc::CHDR_W_64, ENDIANNESS_LITTLE);
-
namespace {
//! Maximum CHDR packet size in bytes
@@ -214,10 +211,12 @@ size_t discover_mtu(const std::string& address,
* Structors
*****************************************************************************/
mpmd_link_if_ctrl_udp::mpmd_link_if_ctrl_udp(const uhd::device_addr_t& mb_args,
- const mpmd_link_if_mgr::xport_info_list_t& xport_info)
+ const mpmd_link_if_mgr::xport_info_list_t& xport_info,
+ const uhd::rfnoc::chdr_w_t chdr_w)
: _mb_args(mb_args)
, _udp_info(get_udp_info_from_xport_info(xport_info))
, _mtu(MPMD_10GE_DATA_FRAME_MAX_SIZE)
+ , _pkt_factory(chdr_w, ENDIANNESS_LITTLE)
{
const bool use_dpdk =
mb_args.has_key("use_dpdk"); // FIXME use constrained_device_args
diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp
index c80f1e613..ebe4f5db2 100644
--- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp
+++ b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_udp.hpp
@@ -10,6 +10,7 @@
#include "mpmd_link_if_ctrl_base.hpp"
#include "mpmd_link_if_mgr.hpp"
#include <uhd/types/device_addr.hpp>
+#include <uhdlib/rfnoc/rfnoc_common.hpp>
#include <unordered_map>
namespace uhd { namespace mpmd { namespace xport {
@@ -30,7 +31,8 @@ public:
using udp_link_info_map = std::unordered_map<std::string, udp_link_info_t>;
mpmd_link_if_ctrl_udp(const uhd::device_addr_t& mb_args,
- const mpmd_link_if_mgr::xport_info_list_t& xport_info);
+ const mpmd_link_if_mgr::xport_info_list_t& xport_info,
+ const uhd::rfnoc::chdr_w_t chdr_w);
size_t get_num_links() const;
uhd::transport::both_links_t get_link(const size_t link_idx,
@@ -51,7 +53,7 @@ private:
std::vector<std::string> _available_addrs;
//! MTU
size_t _mtu;
- static const uhd::rfnoc::chdr::chdr_packet_factory _pkt_factory;
+ const uhd::rfnoc::chdr::chdr_packet_factory _pkt_factory;
};
}}} /* namespace uhd::mpmd::xport */
diff --git a/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp b/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp
index 4b36e7ba4..930f5e465 100644
--- a/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp
+++ b/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp
@@ -36,9 +36,11 @@ public:
/**************************************************************************
* API (see mpmd_link_if_mgr.hpp)
*************************************************************************/
- bool connect(const std::string& link_type, const xport_info_list_t& xport_info)
+ bool connect(const std::string& link_type,
+ const xport_info_list_t& xport_info,
+ const uhd::rfnoc::chdr_w_t chdr_w)
{
- auto link_if_ctrl = make_link_if_ctrl(link_type, xport_info);
+ auto link_if_ctrl = make_link_if_ctrl(link_type, xport_info, chdr_w);
if (!link_if_ctrl) {
UHD_LOG_WARNING(
"MPMD::XPORT", "Unable to create xport ctrl for link type " << link_type);
@@ -89,8 +91,9 @@ private:
/**************************************************************************
* Private methods / helpers
*************************************************************************/
- mpmd_link_if_ctrl_base::uptr make_link_if_ctrl(
- const std::string& link_type, const xport_info_list_t& xport_info)
+ mpmd_link_if_ctrl_base::uptr make_link_if_ctrl(const std::string& link_type,
+ const xport_info_list_t& xport_info,
+ const uhd::rfnoc::chdr_w_t chdr_w)
{
// Here, we hard-code the list of available transport types
if (link_type == "udp") {
@@ -100,7 +103,7 @@ private:
// xport_info);
//}
#endif
- return std::make_unique<mpmd_link_if_ctrl_udp>(_mb_args, xport_info);
+ return std::make_unique<mpmd_link_if_ctrl_udp>(_mb_args, xport_info, chdr_w);
#ifdef HAVE_LIBERIO
} else if (link_type == "liberio") {
return std::make_unique<mpmd_link_if_ctrl_liberio>(_mb_args, xport_info);
diff --git a/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp b/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp
index a1d11bad7..b8e7454cb 100644
--- a/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp
+++ b/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp
@@ -11,6 +11,7 @@
#include <uhd/types/dict.hpp>
#include <uhd/types/direction.hpp>
#include <uhdlib/rfnoc/chdr_packet.hpp>
+#include <uhdlib/rfnoc/rfnoc_common.hpp>
#include <uhdlib/transport/links.hpp>
#include <map>
#include <memory>
@@ -80,8 +81,9 @@ public:
* contain the available IP addresses.
* \returns true on success
*/
- virtual bool connect(
- const std::string& xport_type, const xport_info_list_t& xport_info) = 0;
+ virtual bool connect(const std::string& xport_type,
+ const xport_info_list_t& xport_info,
+ const uhd::rfnoc::chdr_w_t chdr_w) = 0;
/*! The number of available links
*
diff --git a/host/lib/usrp/mpmd/mpmd_mb_iface.cpp b/host/lib/usrp/mpmd/mpmd_mb_iface.cpp
index 41b664374..d4f6cc383 100644
--- a/host/lib/usrp/mpmd/mpmd_mb_iface.cpp
+++ b/host/lib/usrp/mpmd/mpmd_mb_iface.cpp
@@ -62,7 +62,7 @@ void mpmd_mboard_impl::mpmd_mb_iface::init()
"get_chdr_link_options", type);
// User may have specified: addr=192.168.10.2, second_addr=
// MPM may have said: "my addresses are 192.168.10.2 and 192.168.20.2"
- if (_link_if_mgr->connect(type, xport_info)) {
+ if (_link_if_mgr->connect(type, xport_info, get_chdr_w())) {
UHD_LOG_TRACE("MPMD::MB_IFACE", "Link type " << type << " successful.");
}
}
diff --git a/host/tests/rfnoc_chdr_test.cpp b/host/tests/rfnoc_chdr_test.cpp
index 747b3c6a4..27b883543 100644
--- a/host/tests/rfnoc_chdr_test.cpp
+++ b/host/tests/rfnoc_chdr_test.cpp
@@ -74,6 +74,17 @@ strc_payload populate_strc_payload()
return pyld;
}
+mgmt_payload populate_mgmt_payload(const chdr_w_t chdr_w)
+{
+ mgmt_payload pyld;
+ pyld.set_header(sep_id_t(rand64() & 0xFFFF), uint16_t(rand64() & 0xFFFF), chdr_w);
+ mgmt_hop_t hop;
+ // management op payloads are 48 bits
+ hop.add_op(mgmt_op_t(mgmt_op_t::MGMT_OP_NOP, rand64() & 0xFFFFFFFFFFFF));
+ pyld.add_hop(hop);
+ return pyld;
+}
+
void byte_swap(uint64_t* buff)
{
for (size_t i = 0; i < MAX_BUF_SIZE_WORDS; i++) {
@@ -264,3 +275,98 @@ BOOST_AUTO_TEST_CASE(chdr_generic_packet_calculate_pyld_offset_64)
test_pyld_offset(pkt, PKT_TYPE_DATA_WITH_TS, 2);
}
}
+
+
+BOOST_AUTO_TEST_CASE(chdr_mgmt_packet_no_swap_64)
+{
+ uint64_t buff[MAX_BUF_SIZE_WORDS];
+
+ chdr_mgmt_packet::uptr tx_pkt = chdr64_be_factory.make_mgmt();
+ chdr_mgmt_packet::cuptr rx_pkt = chdr64_be_factory.make_mgmt();
+
+ for (size_t i = 0; i < NUM_ITERS; i++) {
+ chdr_header hdr = chdr_header(rand64());
+ mgmt_payload pyld = populate_mgmt_payload(CHDR_W_64);
+
+ memset(buff, 0, MAX_BUF_SIZE_BYTES);
+ tx_pkt->refresh(buff, hdr, pyld);
+ BOOST_CHECK(tx_pkt->get_chdr_header() == hdr);
+ BOOST_CHECK(tx_pkt->get_payload() == pyld);
+
+ rx_pkt->refresh(buff);
+ BOOST_CHECK(rx_pkt->get_chdr_header() == hdr);
+ BOOST_CHECK(rx_pkt->get_payload() == pyld);
+
+ std::cout << pyld.to_string();
+ }
+}
+
+BOOST_AUTO_TEST_CASE(chdr_mgmt_packet_no_swap_256)
+{
+ uint64_t buff[MAX_BUF_SIZE_WORDS];
+
+ chdr_mgmt_packet::uptr tx_pkt = chdr256_be_factory.make_mgmt();
+ chdr_mgmt_packet::cuptr rx_pkt = chdr256_be_factory.make_mgmt();
+
+ for (size_t i = 0; i < NUM_ITERS; i++) {
+ chdr_header hdr = chdr_header(rand64());
+ mgmt_payload pyld = populate_mgmt_payload(CHDR_W_256);
+
+ memset(buff, 0, MAX_BUF_SIZE_BYTES);
+ tx_pkt->refresh(buff, hdr, pyld);
+ BOOST_CHECK(tx_pkt->get_chdr_header() == hdr);
+ BOOST_CHECK(tx_pkt->get_payload() == pyld);
+
+ rx_pkt->refresh(buff);
+ BOOST_CHECK(rx_pkt->get_chdr_header() == hdr);
+ BOOST_CHECK(rx_pkt->get_payload() == pyld);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(chdr_mgmt_packet_swap_64)
+{
+ uint64_t buff[MAX_BUF_SIZE_WORDS];
+
+ chdr_mgmt_packet::uptr tx_pkt = chdr64_be_factory.make_mgmt();
+ chdr_mgmt_packet::cuptr rx_pkt = chdr64_le_factory.make_mgmt();
+
+ for (size_t i = 0; i < NUM_ITERS; i++) {
+ chdr_header hdr = chdr_header(rand64());
+ mgmt_payload pyld = populate_mgmt_payload(CHDR_W_64);
+
+ memset(buff, 0, MAX_BUF_SIZE_BYTES);
+ tx_pkt->refresh(buff, hdr, pyld);
+ BOOST_CHECK(tx_pkt->get_chdr_header() == hdr);
+ BOOST_CHECK(tx_pkt->get_payload() == pyld);
+
+ byte_swap(buff);
+
+ rx_pkt->refresh(buff);
+ BOOST_CHECK(rx_pkt->get_chdr_header() == hdr);
+ BOOST_CHECK(rx_pkt->get_payload() == pyld);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(chdr_mgmt_packet_swap_256)
+{
+ uint64_t buff[MAX_BUF_SIZE_WORDS];
+
+ chdr_mgmt_packet::uptr tx_pkt = chdr256_be_factory.make_mgmt();
+ chdr_mgmt_packet::cuptr rx_pkt = chdr256_le_factory.make_mgmt();
+
+ for (size_t i = 0; i < NUM_ITERS; i++) {
+ chdr_header hdr = chdr_header(rand64());
+ mgmt_payload pyld = populate_mgmt_payload(CHDR_W_256);
+
+ memset(buff, 0, MAX_BUF_SIZE_BYTES);
+ tx_pkt->refresh(buff, hdr, pyld);
+ BOOST_CHECK(tx_pkt->get_chdr_header() == hdr);
+ BOOST_CHECK(tx_pkt->get_payload() == pyld);
+
+ byte_swap(buff);
+
+ rx_pkt->refresh(buff);
+ BOOST_CHECK(rx_pkt->get_chdr_header() == hdr);
+ BOOST_CHECK(rx_pkt->get_payload() == pyld);
+ }
+}