1 //
2 // Copyright 2019 Ettus Research, a National Instruments Brand
3 //
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 //
6 
7 #pragma once
8 
9 #include <uhd/rfnoc/chdr_types.hpp>
10 #include <uhdlib/rfnoc/chdr_ctrl_xport.hpp>
11 #include <uhdlib/rfnoc/chdr_packet_writer.hpp>
12 #include <uhdlib/rfnoc/rfnoc_common.hpp>
13 #include <memory>
14 #include <set>
15 
16 namespace uhd { namespace rfnoc { namespace mgmt {
17 
18 //! A portal to perform low-level management operations from an endpoint
19 //
20 // This object provides an interface to send management commands from a software stream
21 // endpoint. There must one instance of this object per software stream endpoint.
22 // The management portal is capable of discovering all endpoints reachable from the
23 // transport associated with it. It can then setup routes and configure stream endpoints
24 // downstream.
25 class mgmt_portal
26 {
27 public:
28     using uptr           = std::unique_ptr<mgmt_portal>;
29     using xport_cfg_fn_t = std::function<void(
30         device_id_t devid, uint16_t inst, uint8_t subtype, chdr::mgmt_hop_t& hop)>;
31 
32     //! Information about a stream endpoint
33     struct sep_info_t
34     {
35         //! Does the endpoint support control traffic?
36         bool has_ctrl;
37         //! Does the endpoint support data traffic?
38         bool has_data;
39         //! Number of input data ports
40         size_t num_input_ports;
41         //! Number of output data ports
42         size_t num_output_ports;
43         //! Does the endpoint send a stream status packet in case of errors
44         bool reports_strm_errs;
45         //! Address of the endpoint
46         sep_addr_t addr;
47     };
48 
49     virtual ~mgmt_portal() = 0;
50 
51     //! Get addresses for all stream endpoints reachable from this SW mgmt portal
52     //  Note that the endpoints that are not physically connected/reachable from
53     //  the underlying transport will not be discovered.
54     //
55     virtual const std::set<sep_addr_t>& get_reachable_endpoints() const = 0;
56 
57     //! Initialize a stream endpoint and assign an endpoint ID to it
58     //
59     // This should only be called by the epid_allocator
60     //
61     // \param xport The host stream endpoint's CTRL transport
62     // \param addr The physical address of the stream endpoint
63     // \param epid The endpoint ID to assign to this endpoint
64     //
65     virtual void initialize_endpoint(
66         chdr_ctrl_xport& xport, const sep_addr_t& addr, const sep_id_t& epid) = 0;
67 
68     //! Register an already-initialized stream endpoint's endpoint ID
69     //
70     // This should only be called by the epid_allocator
71     //
72     // \param addr The physical address of the stream endpoint
73     // \param epid The endpoint ID to assign to this endpoint
74     //
75     virtual void register_endpoint(const sep_addr_t& addr, const sep_id_t& epid) = 0;
76 
77     //! Get information about a discovered (reachable) stream endpoint
78     //
79     // \param epid The endpoint ID of the endpoint to lookup
80     //
81     virtual bool is_endpoint_registered(const sep_id_t& epid) const = 0;
82 
83     //! Get information about a discovered (reachable) stream endpoint
84     //
85     // \param epid The endpoint ID of the endpoint to lookup
86     //
87     virtual sep_info_t get_endpoint_info(const sep_id_t& epid) const = 0;
88 
89     //! Setup a route from this SW mgmt portal to the specified destination endpoint
90     //
91     //  After a route is established, it should be possible to send packets to the
92     //  destination simply by setting the DstEPID in the CHDR header to the specified
93     //  dst_epid
94     //
95     // \param xport The host stream endpoint's CTRL transport
96     // \param dst_epid The endpoint ID of the destination
97     //
98     virtual void setup_local_route(chdr_ctrl_xport& xport, const sep_id_t& dst_epid) = 0;
99 
100     //! Can a route from between the source and destination endpoints be established?
101     //
102     // \param dst_epid The endpoint ID of the destination
103     // \param src_epid The endpoint ID of the source
104     //
105     virtual bool can_remote_route(
106         const sep_addr_t& dst_addr, const sep_addr_t& src_addr) const = 0;
107 
108     //! Setup a route from between the source and destination endpoints
109     //
110     //  After a route is established, it should be possible for the source to send packets
111     //  to the destination simply by setting the DstEPID in the CHDR header to the
112     //  specified dst_epid
113     //
114     // \param xport The host stream endpoint's CTRL transport
115     // \param dst_epid The endpoint ID of the destination
116     // \param src_epid The endpoint ID of the source
117     //
118     virtual void setup_remote_route(
119         chdr_ctrl_xport& xport, const sep_id_t& dst_epid, const sep_id_t& src_epid) = 0;
120 
121     //! Start configuring a flow controlled receive data stream from the endpoint with the
122     //  specified ID to this SW mgmt portal.
123     //
124     //  RX stream setup is a two-step process. After this function is called, the flow
125     //  control handler needs to acknoweledge the setup transaction then call the commit
126     //  function below.
127     //
128     // \param xport The host stream endpoint's CTRL transport (same EPID as RX stream)
129     // \param epid The endpoint ID of the data source
130     // \param lossy_xport Is the transport lossy? (e.g. UDP, not liberio)
131     // \param pyld_buff_fmt Datatype of SW buffer that holds the data payload
132     // \param mdata_buff_fmt Datatype of SW buffer that holds the data metadata
133     // \param fc_freq Flow control response frequency parameters
134     // \param fc_freq Flow control headroom parameters
135     // \param reset Reset ingress stream endpoint state
136     //
137     virtual void config_local_rx_stream_start(chdr_ctrl_xport& xport,
138         const sep_id_t& epid,
139         const bool lossy_xport,
140         const sw_buff_t pyld_buff_fmt,
141         const sw_buff_t mdata_buff_fmt,
142         const stream_buff_params_t& fc_freq,
143         const stream_buff_params_t& fc_headroom,
144         const bool reset = false) = 0;
145 
146     //! Finish configuring a flow controlled receive data stream from the endpoint with
147     //  the specified ID to this SW mgmt portal.
148     //
149     // \param xport The host stream endpoint's CTRL transport (same EPID as RX stream)
150     // \param epid The endpoint ID of the data source
151     //
152     virtual stream_buff_params_t config_local_rx_stream_commit(
153         chdr_ctrl_xport& xport, const sep_id_t& epid, const double timeout = 0.2) = 0;
154 
155     //! Configure a flow controlled transmit data stream from this SW mgmt portal to the
156     //  endpoint with the specified ID.
157     //
158     // \param xport The host stream endpoint's CTRL transport (same EPID as TX stream)
159     // \param pyld_buff_fmt Datatype of SW buffer that holds the data payload
160     // \param mdata_buff_fmt Datatype of SW buffer that holds the data metadata
161     // \param reset Reset ingress stream endpoint state
162     //
163     virtual void config_local_tx_stream(chdr_ctrl_xport& xport,
164         const sep_id_t& epid,
165         const sw_buff_t pyld_buff_fmt,
166         const sw_buff_t mdata_buff_fmt,
167         const bool reset = false) = 0;
168 
169     //! Configure a flow controlled data stream from the endpoint with ID src_epid to the
170     //  endpoint with ID dst_epid
171     //
172     // \param xport The host stream endpoint's CTRL transport
173     // \param dst_epid The endpoint ID of the destination
174     // \param src_epid The endpoint ID of the source
175     // \param lossy_xport Is the transport lossy?
176     // \param pyld_buff_fmt Datatype of SW buffer that holds the data payload
177     // \param mdata_buff_fmt Datatype of SW buffer that holds the data metadata
178     // \param fc_freq Flow control response frequency parameters
179     // \param fc_freq Flow control headroom parameters
180     //
181     virtual stream_buff_params_t config_remote_stream(chdr_ctrl_xport& xport,
182         const sep_id_t& dst_epid,
183         const sep_id_t& src_epid,
184         const bool lossy_xport,
185         const stream_buff_params_t& fc_freq,
186         const stream_buff_params_t& fc_headroom,
187         const bool reset     = false,
188         const double timeout = 0.2) = 0;
189 
190     //! Define custom configuration functions for custom transports
191     //
192     // \param xport_type The type of the custom transport
193     // \param init_hop_cfg_fn The function to call when initializing the custom xport
194     // \param rtcfg_hop_cfg_fn The function to call when configuring routing for the
195     // custom xport
196     //
197     virtual void register_xport_hop_cfg_fns(uint8_t xport_subtype,
198         xport_cfg_fn_t init_hop_cfg_fn,
199         xport_cfg_fn_t rtcfg_hop_cfg_fn) = 0;
200 
201     //! Create an endpoint manager object
202     //
203     static uptr make(chdr_ctrl_xport& xport,
204         const chdr::chdr_packet_factory& pkt_factory,
205         sep_addr_t my_sep_addr);
206 };
207 
208 }}} // namespace uhd::rfnoc::mgmt
209