aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/lib/include/uhdlib/rfnoc/rfnoc_tx_streamer.hpp10
-rw-r--r--host/lib/include/uhdlib/transport/tx_streamer_impl.hpp29
-rw-r--r--host/lib/rfnoc/rfnoc_tx_streamer.cpp43
3 files changed, 75 insertions, 7 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/rfnoc_tx_streamer.hpp b/host/lib/include/uhdlib/rfnoc/rfnoc_tx_streamer.hpp
index 4acee45cc..3bfc9d05a 100644
--- a/host/lib/include/uhdlib/rfnoc/rfnoc_tx_streamer.hpp
+++ b/host/lib/include/uhdlib/rfnoc/rfnoc_tx_streamer.hpp
@@ -69,6 +69,15 @@ public:
bool check_topology(const std::vector<size_t>& connected_inputs,
const std::vector<size_t>& connected_outputs);
+ /*! Connects a channel to the streamer port
+ *
+ * Overrides method in tx_streamer_impl.
+ *
+ * \param channel The streamer channel to which to connect
+ * \param xport The transport for the specified channel
+ */
+ void connect_channel(const size_t channel, chdr_tx_data_xport::uptr xport);
+
private:
void _register_props(const size_t chan, const std::string& otw_format);
@@ -77,6 +86,7 @@ private:
std::vector<property_t<double>> _samp_rate_out;
std::vector<property_t<double>> _tick_rate_out;
std::vector<property_t<std::string>> _type_out;
+ std::vector<property_t<size_t>> _mtu_out;
// Streamer unique ID
const std::string _unique_id;
diff --git a/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp b/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp
index 60881dad2..819ed5558 100644
--- a/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp
+++ b/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp
@@ -79,14 +79,14 @@ public:
_spp = stream_args.args.cast<size_t>("spp", _spp);
}
- void connect_channel(const size_t channel, typename transport_t::uptr xport)
+ virtual void connect_channel(const size_t channel, typename transport_t::uptr xport)
{
- const size_t max_pyld_size = xport->get_max_payload_size();
+ const size_t mtu = xport->get_max_payload_size();
_zero_copy_streamer.connect_channel(channel, std::move(xport));
- // Set spp based on the transport frame size
- const size_t xport_spp = max_pyld_size / _convert_info.bytes_per_otw_item;
- _spp = std::min(_spp, xport_spp);
+ if (mtu < _mtu) {
+ set_mtu(mtu);
+ }
}
size_t get_num_channels() const
@@ -187,6 +187,22 @@ public:
}
protected:
+ //! Returns the size in bytes of a sample in a packet
+ size_t get_mtu() const
+ {
+ return _mtu;
+ }
+
+ //! Sets the MTU and calculates spp
+ void set_mtu(const size_t mtu)
+ {
+ _mtu = mtu;
+
+ // Check if spp needs to be lowered. SPP may already be lower than the
+ // value allowed by mtu if the user specified it using stream_args.
+ _spp = std::min(_spp, _mtu / _convert_info.bytes_per_otw_item);
+ }
+
//! Configures scaling factor for conversion
void set_scale_factor(const size_t chan, const double scale_factor)
{
@@ -295,6 +311,9 @@ private:
// Sample rate used to calculate metadata time_spec_t
double _samp_rate = 1.0;
+ // Maximum payload size
+ size_t _mtu = std::numeric_limits<std::size_t>::max();
+
// Maximum number of samples per packet
size_t _spp = std::numeric_limits<std::size_t>::max();
diff --git a/host/lib/rfnoc/rfnoc_tx_streamer.cpp b/host/lib/rfnoc/rfnoc_tx_streamer.cpp
index 82feeaf1f..61d714a85 100644
--- a/host/lib/rfnoc/rfnoc_tx_streamer.cpp
+++ b/host/lib/rfnoc/rfnoc_tx_streamer.cpp
@@ -30,11 +30,35 @@ rfnoc_tx_streamer::rfnoc_tx_streamer(const size_t num_chans,
_samp_rate_out.reserve(num_chans);
_tick_rate_out.reserve(num_chans);
_type_out.reserve(num_chans);
+ _mtu_out.reserve(num_chans);
for (size_t i = 0; i < num_chans; i++) {
_register_props(i, stream_args.otw_format);
}
+ for (size_t i = 0; i < num_chans; i++) {
+ prop_ptrs_t mtu_resolver_out;
+ for (auto& mtu_prop : _mtu_out) {
+ mtu_resolver_out.insert(&mtu_prop);
+ }
+ //property_t<size_t>* mtu_out = &_mtu_out.back();
+
+ add_property_resolver({&_mtu_out[i]}, std::move(mtu_resolver_out),
+ [&mtu_out = _mtu_out[i], i, this]() {
+ RFNOC_LOG_TRACE("Calling resolver for `mtu_out'@" << i);
+ if (mtu_out.is_valid()) {
+ const size_t mtu = mtu_out.get();
+ // If the current MTU changes, set the same value for all chans
+ if (mtu < tx_streamer_impl::get_mtu()) {
+ for (auto& prop : this->_mtu_out) {
+ prop.set(mtu);
+ }
+ tx_streamer_impl::set_mtu(mtu);
+ }
+ }
+ });
+ }
+
node_accessor_t node_accessor;
node_accessor.init_props(this);
}
@@ -72,8 +96,19 @@ bool rfnoc_tx_streamer::check_topology(
return node_t::check_topology(connected_inputs, connected_outputs);
}
-void rfnoc_tx_streamer::_register_props(const size_t chan,
- const std::string& otw_format)
+void rfnoc_tx_streamer::connect_channel(
+ const size_t channel, chdr_tx_data_xport::uptr xport)
+{
+ UHD_ASSERT_THROW(channel < _mtu_out.size());
+
+ // Update MTU property based on xport limits
+ const size_t mtu = xport->get_max_payload_size();
+ set_property<size_t>(PROP_KEY_MTU, mtu, {res_source_info::OUTPUT_EDGE, channel});
+
+ tx_streamer_impl<chdr_tx_data_xport>::connect_channel(channel, std::move(xport));
+}
+
+void rfnoc_tx_streamer::_register_props(const size_t chan, const std::string& otw_format)
{
// Create actual properties and store them
_scaling_out.push_back(property_t<double>(
@@ -84,18 +119,22 @@ void rfnoc_tx_streamer::_register_props(const size_t chan,
PROP_KEY_TICK_RATE, {res_source_info::OUTPUT_EDGE, chan}));
_type_out.emplace_back(property_t<std::string>(
PROP_KEY_TYPE, otw_format, {res_source_info::OUTPUT_EDGE, chan}));
+ _mtu_out.push_back(property_t<size_t>(
+ PROP_KEY_MTU, {res_source_info::OUTPUT_EDGE, chan}));
// Give us some shorthands for the rest of this function
property_t<double>* scaling_out = &_scaling_out.back();
property_t<double>* samp_rate_out = &_samp_rate_out.back();
property_t<double>* tick_rate_out = &_tick_rate_out.back();
property_t<std::string>* type_out = &_type_out.back();
+ property_t<size_t>* mtu_out = &_mtu_out.back();
// Register them
register_property(scaling_out);
register_property(samp_rate_out);
register_property(tick_rate_out);
register_property(type_out);
+ register_property(mtu_out);
// Add resolvers
add_property_resolver({scaling_out}, {},