diff options
Diffstat (limited to 'host/lib/include')
5 files changed, 108 insertions, 18 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp b/host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp index cb0987446..08930f9f3 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_rx_data_xport.hpp @@ -177,13 +177,41 @@ public: */ ~chdr_rx_data_xport(); - /*! Returns maximum number payload bytes + /*! Returns MTU for this transport in bytes * - * \return maximum payload bytes per packet + * MTU is the max size for CHDR packets, including headers. For most + * applications, get_max_payload_size() is probably the more useful method. + * Compare also noc_block_base::get_mtu(). + * + * \return MTU in bytes + */ + size_t get_mtu() const + { + return _mtu; + } + + /*! Return the size of a CHDR packet header, in bytes. + * + * This helper function factors in the CHDR width for this transport. + * Compare also noc_block_base::get_chdr_hdr_len(). + * + * \returns the length of a CHDR header in bytes + */ + size_t get_chdr_hdr_len() const + { + return _hdr_len; + } + + /*! Returns maximum number of payload bytes + * + * This is smaller than the MTU. Compare also + * noc_block_base::get_max_payload_size(). + * + * \return maximum number of payload bytes */ size_t get_max_payload_size() const { - return _max_payload_size; + return _mtu - _hdr_len; } /*! @@ -389,8 +417,11 @@ private: // Flow control state rx_flow_ctrl_state _fc_state; - // Maximum data payload in bytes - size_t _max_payload_size = 0; + // MTU in bytes + size_t _mtu = 0; + + // Size of CHDR headers + size_t _hdr_len = 0; // Sequence number for data packets uint16_t _data_seq_num = 0; diff --git a/host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp b/host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp index 4e8ebe24d..e0887db6c 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_tx_data_xport.hpp @@ -175,13 +175,41 @@ public: */ ~chdr_tx_data_xport(); + /*! Returns MTU for this transport in bytes + * + * MTU is the max size for CHDR packets, including headers. For most + * applications, get_max_payload_size() is probably the more useful method. + * Compare also noc_block_base::get_mtu(). + * + * \return MTU in bytes + */ + size_t get_mtu() const + { + return _mtu; + } + + /*! Return the size of a CHDR packet header, in bytes. + * + * This helper function factors in the CHDR width for this transport. + * Compare also noc_block_base::get_chdr_hdr_len(). + * + * \returns the length of a CHDR header in bytes + */ + size_t get_chdr_hdr_len() const + { + return _hdr_len; + } + /*! Returns maximum number of payload bytes * + * This is smaller than the MTU. Compare also + * noc_block_base::get_max_payload_size(). + * * \return maximum number of payload bytes */ size_t get_max_payload_size() const { - return _max_payload_size; + return _mtu - _hdr_len; } /*! @@ -373,8 +401,11 @@ private: // Flow control state tx_flow_ctrl_state _fc_state; - // Maximum data payload in bytes - size_t _max_payload_size = 0; + // MTU in bytes + size_t _mtu = 0; + + // Size of CHDR headers + size_t _hdr_len = 0; // Sequence number for data packets uint16_t _data_seq_num = 0; diff --git a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp index b60b0f2a2..e268dbc07 100644 --- a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp +++ b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp @@ -356,6 +356,15 @@ private: const std::vector<uint32_t>& data, boost::optional<uint64_t> timestamp); + //! Return the maximum samples per packet of size \p bytes + // + // Given a packet of size \p bytes, how many samples can we fit in there? + // This gives the answer, factoring in item size and samples per clock. + // + // \param bytes Number of bytes we can fill with samples (excluding bytes + // required for CHDR headers!) + int get_max_spp(const size_t bytes); + //! FPGA compat number const uint32_t _fpga_compat; diff --git a/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp b/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp index 79c196f3f..f776d9373 100644 --- a/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp +++ b/host/lib/include/uhdlib/transport/rx_streamer_impl.hpp @@ -88,7 +88,6 @@ public: if (stream_args.args.has_key("spp")) { _spp = stream_args.args.cast<size_t>("spp", _spp); - _mtu = _spp * _convert_info.bytes_per_otw_item; } } @@ -97,7 +96,8 @@ public: // them virtual void connect_channel(const size_t channel, typename transport_t::uptr xport) { - const size_t mtu = xport->get_max_payload_size(); + const size_t mtu = xport->get_mtu(); + _hdr_len = std::max(_hdr_len, xport->get_chdr_hdr_len()); _zero_copy_streamer.connect_channel(channel, std::move(xport)); if (mtu < _mtu) { @@ -201,11 +201,15 @@ protected: return _mtu; } - //! Sets the MTU and calculates spp + //! Sets the MTU and checks spp. If spp would exceed the new MTU, it is + // reduced accordingly. void set_mtu(const size_t mtu) { _mtu = mtu; - _spp = _mtu / _convert_info.bytes_per_otw_item; + const size_t spp_from_mtu = (_mtu - _hdr_len) / _convert_info.bytes_per_otw_item; + if (spp_from_mtu < _spp) { + _spp = spp_from_mtu; + } } //! Configures sample rate for conversion of timestamp @@ -401,7 +405,12 @@ private: // MTU, determined when xport is connected and modifiable by subclass size_t _mtu = std::numeric_limits<std::size_t>::max(); - // Maximum number of samples per packet + // Size of CHDR header in bytes + size_t _hdr_len = 0; + + // Maximum number of samples per packet. Note that this is not necessarily + // related to the MTU, it is a user-chosen value. However, it is always + // bounded by the MTU. size_t _spp = std::numeric_limits<std::size_t>::max(); // Num samps remaining in buffer currently held by zero copy streamer diff --git a/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp b/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp index f814c8192..9dc3b0c35 100644 --- a/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp +++ b/host/lib/include/uhdlib/transport/tx_streamer_impl.hpp @@ -11,6 +11,7 @@ #include <uhd/stream.hpp> #include <uhd/types/metadata.hpp> #include <uhd/utils/tasks.hpp> +#include <uhd/utils/log.hpp> #include <uhdlib/transport/tx_streamer_zero_copy.hpp> #include <limits> #include <vector> @@ -111,13 +112,13 @@ public: if (stream_args.args.has_key("spp")) { _spp = stream_args.args.cast<size_t>("spp", _spp); - _mtu = _spp * _convert_info.bytes_per_otw_item; } } virtual void connect_channel(const size_t channel, typename transport_t::uptr xport) { - const size_t mtu = xport->get_max_payload_size(); + const size_t mtu = xport->get_mtu(); + _hdr_len = std::max(_hdr_len, xport->get_chdr_hdr_len()); _zero_copy_streamer.connect_channel(channel, std::move(xport)); if (mtu < _mtu) { @@ -323,11 +324,15 @@ protected: return _mtu; } - //! Sets the MTU and calculates spp + //! Sets the MTU and checks spp. If spp would exceed the new MTU, it is + // reduced accordingly. void set_mtu(const size_t mtu) { _mtu = mtu; - _spp = _mtu / _convert_info.bytes_per_otw_item; + const size_t spp_from_mtu = (_mtu - _hdr_len) / _convert_info.bytes_per_otw_item; + if (spp_from_mtu < _spp) { + _spp = spp_from_mtu; + } } //! Configures scaling factor for conversion @@ -444,7 +449,12 @@ private: // MTU, determined when xport is connected and modifiable by subclass size_t _mtu = std::numeric_limits<std::size_t>::max(); - // Maximum number of samples per packet + // Size of CHDR header in bytes + size_t _hdr_len = 0; + + // Maximum number of samples per packet. Note that this is not necessarily + // related to the MTU, it is a user-chosen value. However, it is always + // bounded by the MTU. size_t _spp = std::numeric_limits<std::size_t>::max(); // Metadata cache for send calls with no data |