aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp')
-rw-r--r--host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp b/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp
new file mode 100644
index 000000000..937baf982
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp
@@ -0,0 +1,130 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP
+#define INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP
+
+#include <uhd/utils/log.hpp>
+#include <uhdlib/rfnoc/rfnoc_common.hpp>
+
+namespace uhd { namespace rfnoc {
+
+//! Class to manage rx flow control state
+class rx_flow_ctrl_state
+{
+public:
+ //! Constructor
+ rx_flow_ctrl_state(const rfnoc::sep_id_pair_t epids) : _epids(epids) {}
+
+ //! Initialize frequency parameters
+ void initialize(const stream_buff_params_t fc_freq)
+ {
+ _fc_freq = fc_freq;
+ }
+
+ //! Resynchronize with transfer counts from the sender
+ void resynchronize(const stream_buff_params_t counts)
+ {
+ if (_recv_counts.bytes != counts.bytes
+ || _recv_counts.packets != counts.packets) {
+ // If there is a discrepancy between the amount of data sent by
+ // the device and received by the transport, adjust the counts
+ // of data received and transferred to include the dropped data.
+ auto bytes_dropped = counts.bytes - _recv_counts.bytes;
+ auto pkts_dropped = counts.packets - _recv_counts.packets;
+ _xfer_counts.bytes += bytes_dropped;
+ _xfer_counts.packets += pkts_dropped;
+
+ UHD_LOGGER_DEBUG("rx_flow_ctrl_state")
+ << "oh noes: bytes_sent=" << counts.bytes
+ << " bytes_received=" << _recv_counts.bytes
+ << " pkts_sent=" << counts.packets
+ << " pkts_received=" << _recv_counts.packets
+ << " src_epid=" << _epids.first << " dst_epid=" << _epids.second
+ << std::endl;
+
+ _recv_counts = counts;
+ }
+ }
+
+ //! Reset the transfer counts (happens during init)
+ void reset_counts()
+ {
+ UHD_LOGGER_TRACE("rx_flow_ctrl_state")
+ << "Resetting transfer counts" << std::endl;
+ _recv_counts = {0, 0};
+ _xfer_counts = {0, 0};
+ }
+
+ //! Update state when data is received
+ void data_received(const size_t bytes)
+ {
+ _recv_counts.bytes += bytes;
+ _recv_counts.packets++;
+ }
+
+ //! Update state when transfer is complete (buffer space freed)
+ void xfer_done(const size_t bytes)
+ {
+ _xfer_counts.bytes += bytes;
+ _xfer_counts.packets++;
+ }
+
+ //! Returns whether a flow control response is needed
+ bool fc_resp_due() const
+ {
+ stream_buff_params_t accum_counts = {
+ _xfer_counts.bytes - _last_fc_resp_counts.bytes,
+ _xfer_counts.packets - _last_fc_resp_counts.packets};
+
+ return accum_counts.bytes >= _fc_freq.bytes
+ || accum_counts.packets >= _fc_freq.packets;
+ }
+
+ //! Update state after flow control response was sent
+ void fc_resp_sent()
+ {
+ _last_fc_resp_counts = _xfer_counts;
+ }
+
+ //! Returns counts for completed transfers
+ stream_buff_params_t get_xfer_counts() const
+ {
+ return _xfer_counts;
+ }
+
+ //! Returns counts for completed transfers
+ stream_buff_params_t get_recv_counts() const
+ {
+ return _recv_counts;
+ }
+
+ //! Returns configured flow control frequency
+ stream_buff_params_t get_fc_freq() const
+ {
+ return _fc_freq;
+ }
+
+private:
+ // Counts for data received, including any data still in use
+ stream_buff_params_t _recv_counts{0, 0};
+
+ // Counts for data read and whose buffer space is ok to reuse
+ stream_buff_params_t _xfer_counts{0, 0};
+
+ // Counts sent in last flow control response
+ stream_buff_params_t _last_fc_resp_counts{0, 0};
+
+ // Frequency of flow control responses
+ stream_buff_params_t _fc_freq{0, 0};
+
+ // Endpoint ID for log messages
+ const sep_id_pair_t _epids;
+};
+
+}} // namespace uhd::rfnoc
+
+#endif /* INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP */