diff options
author | Martin Braun <martin.braun@ettus.com> | 2019-07-03 20:15:35 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-11-26 12:16:25 -0800 |
commit | c256b9df6502536c2e451e690f1ad5962c664d1a (patch) | |
tree | a83ad13e6f5978bbe14bb3ecf8294ba1e3d28db4 /host/lib/usrp/x300/x300_mb_iface.cpp | |
parent | 9a8435ed998fc5c65257f4c55768750b227ab19e (diff) | |
download | uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.tar.gz uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.tar.bz2 uhd-c256b9df6502536c2e451e690f1ad5962c664d1a.zip |
x300/mpmd: Port all RFNoC devices to the new RFNoC framework
Co-Authored-By: Alex Williams <alex.williams@ni.com>
Co-Authored-By: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-Authored-By: Brent Stapleton <brent.stapleton@ettus.com>
Co-Authored-By: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Diffstat (limited to 'host/lib/usrp/x300/x300_mb_iface.cpp')
-rw-r--r-- | host/lib/usrp/x300/x300_mb_iface.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/host/lib/usrp/x300/x300_mb_iface.cpp b/host/lib/usrp/x300/x300_mb_iface.cpp new file mode 100644 index 000000000..2c053080d --- /dev/null +++ b/host/lib/usrp/x300/x300_mb_iface.cpp @@ -0,0 +1,226 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include "x300_impl.hpp" +#include <uhdlib/rfnoc/device_id.hpp> + +using namespace uhd::rfnoc; +using uhd::transport::link_type_t; + + +x300_impl::x300_mb_iface::x300_mb_iface(uhd::usrp::x300::conn_manager::sptr conn_mgr, + const double radio_clk_freq, + const uhd::rfnoc::device_id_t remote_dev_id) + : _remote_dev_id(remote_dev_id) + , _bus_clk(std::make_shared<uhd::rfnoc::clock_iface>( + "bus_clk", uhd::usrp::x300::BUS_CLOCK_RATE, false)) + , _radio_clk( + std::make_shared<uhd::rfnoc::clock_iface>("radio_clk", radio_clk_freq, false)) + , _conn_mgr(conn_mgr) +{ + UHD_ASSERT_THROW(_conn_mgr); + _bus_clk->set_running(true); + _radio_clk->set_running(true); +} + +x300_impl::x300_mb_iface::~x300_mb_iface() = default; + +uint16_t x300_impl::x300_mb_iface::get_proto_ver() +{ + // TODO: Get from from a hardware register + return 0x0100; +} + +uhd::rfnoc::chdr_w_t x300_impl::x300_mb_iface::get_chdr_w() +{ + // TODO: Get from from a hardware register + return uhd::rfnoc::CHDR_W_64; +} + +uhd::endianness_t x300_impl::x300_mb_iface::get_endianness( + const uhd::rfnoc::device_id_t /*local_device_id*/) +{ + // FIXME + return uhd::ENDIANNESS_BIG; +} + +uhd::rfnoc::device_id_t x300_impl::x300_mb_iface::get_remote_device_id() +{ + return _remote_dev_id; +} + +std::vector<uhd::rfnoc::device_id_t> x300_impl::x300_mb_iface::get_local_device_ids() +{ + return _conn_mgr->get_local_device_ids(); +} + +uhd::transport::adapter_id_t x300_impl::x300_mb_iface::get_adapter_id( + const uhd::rfnoc::device_id_t local_device_id) +{ + return _adapter_map[local_device_id]; +} + +void x300_impl::x300_mb_iface::reset_network() +{ + // FIXME +} + +uhd::rfnoc::clock_iface::sptr x300_impl::x300_mb_iface::get_clock_iface( + const std::string& clock_name) +{ + if (clock_name == "radio_clk") { + return _radio_clk; + } + if (clock_name == "bus_clk") { + return _bus_clk; + } + UHD_LOG_ERROR("X300", "Invalid timebase clock name: " + clock_name); + throw uhd::key_error("[X300] Invalid timebase clock name: " + clock_name); +} + +uhd::rfnoc::chdr_ctrl_xport::sptr x300_impl::x300_mb_iface::make_ctrl_transport( + uhd::rfnoc::device_id_t local_device_id, const uhd::rfnoc::sep_id_t& local_epid) +{ + uhd::transport::io_service::sptr io_srv; + uhd::transport::send_link_if::sptr send_link; + uhd::transport::recv_link_if::sptr recv_link; + std::tie(io_srv, send_link, std::ignore, recv_link, std::ignore, std::ignore) = + _conn_mgr->get_links(link_type_t::CTRL, + local_device_id, + local_epid, + uhd::rfnoc::sep_id_t(), + uhd::device_addr_t()); + + /* Associate local device ID with the adapter */ + _adapter_map[local_device_id] = send_link->get_send_adapter_id(); + + auto xport = uhd::rfnoc::chdr_ctrl_xport::make(io_srv, + send_link, + recv_link, + _pkt_factory, + local_epid, + send_link->get_num_send_frames(), + recv_link->get_num_recv_frames()); + return xport; +} + +uhd::rfnoc::chdr_rx_data_xport::uptr x300_impl::x300_mb_iface::make_rx_data_transport( + uhd::rfnoc::mgmt::mgmt_portal& mgmt_portal, + const uhd::rfnoc::sep_addr_pair_t& addrs, + const uhd::rfnoc::sep_id_pair_t& epids, + const uhd::rfnoc::sw_buff_t pyld_buff_fmt, + const uhd::rfnoc::sw_buff_t mdata_buff_fmt, + const uhd::device_addr_t& xport_args) +{ + const uhd::rfnoc::sep_addr_t local_sep_addr = addrs.second; + const uhd::rfnoc::sep_id_t remote_epid = epids.first; + const uhd::rfnoc::sep_id_t local_epid = epids.second; + + uhd::transport::io_service::sptr io_srv; + uhd::transport::send_link_if::sptr send_link; + uhd::transport::recv_link_if::sptr recv_link; + size_t recv_buff_size; + bool lossy_xport; + std::tie(io_srv, send_link, std::ignore, recv_link, recv_buff_size, lossy_xport) = + _conn_mgr->get_links(link_type_t::RX_DATA, + local_sep_addr.first, + local_epid, + remote_epid, + xport_args); + + /* Associate local device ID with the adapter */ + _adapter_map[local_sep_addr.first] = send_link->get_send_adapter_id(); + + // TODO: configure this based on the transport type + const uhd::rfnoc::stream_buff_params_t recv_capacity = { + recv_buff_size, uhd::rfnoc::MAX_FC_CAPACITY_PKTS}; + + const double ratio = 1.0 / 32; + + // Configure flow control frequency to use bytes only for UDP + uhd::rfnoc::stream_buff_params_t fc_freq = { + static_cast<uint64_t>(std::ceil(double(recv_buff_size) * ratio)), + uhd::rfnoc::MAX_FC_FREQ_PKTS}; + + uhd::rfnoc::stream_buff_params_t fc_headroom = {0, 0}; + + // Create the data transport + auto fc_params = uhd::rfnoc::chdr_rx_data_xport::configure_sep(io_srv, + recv_link, + send_link, + _pkt_factory, + mgmt_portal, + epids, + pyld_buff_fmt, + mdata_buff_fmt, + recv_capacity, + fc_freq, + fc_headroom, + lossy_xport); + + auto rx_xport = std::make_unique<uhd::rfnoc::chdr_rx_data_xport>(io_srv, + recv_link, + send_link, + _pkt_factory, + epids, + recv_link->get_num_recv_frames(), + fc_params); + + return rx_xport; +} + +uhd::rfnoc::chdr_tx_data_xport::uptr x300_impl::x300_mb_iface::make_tx_data_transport( + uhd::rfnoc::mgmt::mgmt_portal& mgmt_portal, + const uhd::rfnoc::sep_addr_pair_t& addrs, + const uhd::rfnoc::sep_id_pair_t& epids, + const uhd::rfnoc::sw_buff_t pyld_buff_fmt, + const uhd::rfnoc::sw_buff_t mdata_buff_fmt, + const uhd::device_addr_t& xport_args) +{ + const uhd::rfnoc::sep_addr_t local_sep_addr = addrs.first; + const uhd::rfnoc::sep_id_t remote_epid = epids.second; + const uhd::rfnoc::sep_id_t local_epid = epids.first; + + uhd::transport::io_service::sptr io_srv; + uhd::transport::send_link_if::sptr send_link; + uhd::transport::recv_link_if::sptr recv_link; + bool lossy_xport; + std::tie(io_srv, send_link, std::ignore, recv_link, std::ignore, lossy_xport) = + _conn_mgr->get_links(link_type_t::TX_DATA, + local_sep_addr.first, + local_epid, + remote_epid, + xport_args); + + /* Associate local device ID with the adapter */ + _adapter_map[local_sep_addr.first] = send_link->get_send_adapter_id(); + + // TODO: configure this based on the transport type + const double fc_freq_ratio = 1.0 / 8; + const double fc_headroom_ratio = 0; + + const auto buff_capacity = chdr_tx_data_xport::configure_sep(io_srv, + recv_link, + send_link, + _pkt_factory, + mgmt_portal, + epids, + pyld_buff_fmt, + mdata_buff_fmt, + fc_freq_ratio, + fc_headroom_ratio); + + // Create the data transport + auto tx_xport = std::make_unique<chdr_tx_data_xport>(io_srv, + recv_link, + send_link, + _pkt_factory, + epids, + send_link->get_num_send_frames(), + buff_capacity); + + return tx_xport; +} |