diff options
author | Alex Williams <alex.williams@ni.com> | 2019-05-30 15:09:10 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 11:49:26 -0800 |
commit | 53477bfc7ffb2dc09143e1c9e8e431efc8ada957 (patch) | |
tree | 7dc7ab3ffd45ed2c07544fa391979ad6a5916f16 /host/lib/rfnoc | |
parent | 4b23b6102c182e4f5a8612e16752d34465bf190c (diff) | |
download | uhd-53477bfc7ffb2dc09143e1c9e8e431efc8ada957.tar.gz uhd-53477bfc7ffb2dc09143e1c9e8e431efc8ada957.tar.bz2 uhd-53477bfc7ffb2dc09143e1c9e8e431efc8ada957.zip |
rfnoc: Add chdr_ctrl_xport
chdr_ctrl_xport is a dumb-pipe transport for RFNoC control transactions
and management frames.
Also remove the I/O service's check on num_recv_frames and num_send_frames.
The transports may request additional virtual channels, so the send_io_if
and recv_io_if may not reserve additional frames, as they are shared with
a previously-allocated instance.
Note: this uses a mutex to force sequentual access to the
chdr_ctrl_xport. This is supposed to go away when the multi threaded
xport is done.
Diffstat (limited to 'host/lib/rfnoc')
-rw-r--r-- | host/lib/rfnoc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | host/lib/rfnoc/chdr_ctrl_xport.cpp | 147 |
2 files changed, 148 insertions, 0 deletions
diff --git a/host/lib/rfnoc/CMakeLists.txt b/host/lib/rfnoc/CMakeLists.txt index 0f9d62c51..93e7ff5b2 100644 --- a/host/lib/rfnoc/CMakeLists.txt +++ b/host/lib/rfnoc/CMakeLists.txt @@ -22,6 +22,7 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/block_id.cpp ${CMAKE_CURRENT_SOURCE_DIR}/chdr_types.cpp ${CMAKE_CURRENT_SOURCE_DIR}/chdr_packet.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/chdr_ctrl_xport.cpp ${CMAKE_CURRENT_SOURCE_DIR}/client_zero.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ctrl_iface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/device_id.cpp diff --git a/host/lib/rfnoc/chdr_ctrl_xport.cpp b/host/lib/rfnoc/chdr_ctrl_xport.cpp new file mode 100644 index 000000000..72fe5bf7f --- /dev/null +++ b/host/lib/rfnoc/chdr_ctrl_xport.cpp @@ -0,0 +1,147 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include <uhd/utils/log.hpp> +#include <uhdlib/rfnoc/chdr_ctrl_xport.hpp> +#include <uhdlib/rfnoc/chdr_types.hpp> + +using namespace uhd; +using namespace uhd::rfnoc; +using namespace uhd::rfnoc::chdr; +using namespace uhd::transport; + +chdr_ctrl_xport::chdr_ctrl_xport(io_service::sptr io_srv, + send_link_if::sptr send_link, + recv_link_if::sptr recv_link, + sep_id_t my_epid, + size_t num_send_frames, + size_t num_recv_frames) + : _my_epid(my_epid) +{ + /* Make dumb send pipe */ + send_io_if::send_callback_t send_cb = [this](frame_buff::uptr& buff, + send_link_if* link) { + link->release_send_buff(std::move(buff)); + }; + _send_if = io_srv->make_send_client( + send_link, num_send_frames, send_cb, recv_link_if::sptr(), 0, nullptr); + + /* Make dumb recv pipe that matches management and control packets */ + uhd::transport::recv_callback_t ctrl_recv_cb = [this](frame_buff::uptr& buff, + recv_link_if* /*recv_link*/, + send_link_if + * /*send_link*/) -> bool { + uint64_t* data = (uint64_t*)buff->data(); + auto hdr = chdr_header(uhd::ntohx<uint64_t>(*data)); + auto pkt_type = hdr.get_pkt_type(); + auto dst_epid = hdr.get_dst_epid(); + + /* Check type and destination EPID */ + if ((pkt_type == PKT_TYPE_CTRL) && (dst_epid == _my_epid)) { + return true; + } else { + return false; + } + return false; + }; + recv_io_if::fc_callback_t release_cb = + [](frame_buff::uptr buff, recv_link_if* link, send_link_if* /*send_link*/) { + link->release_recv_buff(std::move(buff)); + }; + + _ctrl_recv_if = io_srv->make_recv_client(recv_link, + num_recv_frames, + ctrl_recv_cb, + send_link_if::sptr(), + 0, + release_cb); + + uhd::transport::recv_callback_t mgmt_recv_cb = [this](frame_buff::uptr& buff, + recv_link_if* /*recv_link*/, + send_link_if + * /*send_link*/) -> bool { + uint64_t* data = (uint64_t*)buff->data(); + auto hdr = chdr_header(uhd::ntohx<uint64_t>(*data)); + auto pkt_type = hdr.get_pkt_type(); + auto dst_epid = hdr.get_dst_epid(); + + /* Check type and destination EPID */ + if ((pkt_type == PKT_TYPE_MGMT) && (dst_epid == _my_epid)) { + return true; + } else { + return false; + } + return false; + }; + + // No additional frames reserved specifically for this virtual interface + _mgmt_recv_if = io_srv->make_recv_client( + recv_link, 0, mgmt_recv_cb, send_link_if::sptr(), 0, release_cb); +} + +/*! + * Get an empty frame buffer in which to write packet contents. + * + * \param timeout_ms a positive timeout value specifies the maximum number + of ms to wait, a negative value specifies to block + until successful, and a value of 0 specifies no wait. + * \return a frame buffer, or null uptr if timeout occurs + */ +frame_buff::uptr chdr_ctrl_xport::get_send_buff(int32_t timeout_ms) +{ + // FIXME: Remove mutex when have threaded_io_service + std::lock_guard<std::mutex> lock(_mutex); + frame_buff::uptr buff = _send_if->get_send_buff(timeout_ms); + if (!buff) { + return frame_buff::uptr(); + } + return frame_buff::uptr(std::move(buff)); +} + +/*! + * Release a frame buffer, allowing the driver to reuse it. + * + * \param buffer frame buffer to release for reuse by the link + */ +void chdr_ctrl_xport::release_send_buff(frame_buff::uptr buff) +{ + // FIXME: Remove mutex when have threaded_io_service + std::lock_guard<std::mutex> lock(_mutex); + _send_if->release_send_buff(std::move(buff)); +} + +/*! + * Attempt to get a frame buffer with data from the recv link. + * + * \param timeout_ms a positive timeout value specifies the maximum number + of ms to wait, a negative value specifies to block + until successful, and a value of 0 specifies no wait. + * \return a frame buffer, or null uptr if timeout occurs + */ +frame_buff::uptr chdr_ctrl_xport::get_recv_buff(int32_t timeout_ms) +{ + // FIXME: Remove mutex when have threaded_io_service + std::lock_guard<std::mutex> lock(_mutex); + return _ctrl_recv_if->get_recv_buff(timeout_ms); +} + +frame_buff::uptr chdr_ctrl_xport::get_mgmt_buff(int32_t timeout_ms) +{ + std::lock_guard<std::mutex> lock(_mutex); + return _mgmt_recv_if->get_recv_buff(timeout_ms); +} + +/*! + * Release a frame buffer, allowing the recv link driver to reuse it. + * + * \param buffer frame buffer to release for reuse by the link + */ +void chdr_ctrl_xport::release_recv_buff(frame_buff::uptr buff) +{ + // FIXME: Remove mutex when have threaded_io_service + std::lock_guard<std::mutex> lock(_mutex); + _ctrl_recv_if->release_recv_buff(std::move(buff)); +} |