aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/include/uhdlib/rfnoc/rx_flow_ctrl_state.hpp
blob: ed6553bf3e591d644b2a2b9bd2e0945d675e5637 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//
// 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, const stream_buff_params_t fc_freq)
        : _fc_freq(fc_freq), _epids(epids)
    {
    }

    //! 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;
        }
    }

    //! 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 */