diff options
| -rw-r--r-- | host/lib/include/uhdlib/rfnoc/chdr_types.hpp | 2 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/rfnoc/epid_allocator.hpp | 13 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp | 15 | ||||
| -rw-r--r-- | host/lib/rfnoc/epid_allocator.cpp | 19 | ||||
| -rw-r--r-- | host/lib/rfnoc/link_stream_manager.cpp | 25 | ||||
| -rw-r--r-- | host/lib/rfnoc/mgmt_portal.cpp | 31 | 
6 files changed, 80 insertions, 25 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp index 1f14ea7d0..b5725710b 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp @@ -802,7 +802,7 @@ public:      const std::string to_string() const;      //! Return the source EPID for this transaction -    inline const sep_id_t get_src_epid() const +    inline sep_id_t get_src_epid() const      {          return _src_epid;      } diff --git a/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp b/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp index ec23dcb50..8306b98a4 100644 --- a/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp +++ b/host/lib/include/uhdlib/rfnoc/epid_allocator.hpp @@ -7,6 +7,7 @@  #ifndef INCLUDED_LIBUHD_EPID_ALLOCATOR_HPP  #define INCLUDED_LIBUHD_EPID_ALLOCATOR_HPP +#include <uhdlib/rfnoc/mgmt_portal.hpp>  #include <uhdlib/rfnoc/rfnoc_common.hpp>  #include <map>  #include <memory> @@ -27,12 +28,24 @@ public:      epid_allocator(epid_allocator&& rhs)      = delete;      /*! \brief Allocate an EPID for the specified endpoint. +     * Does not initialize the specified endpoint (ideal for SW endpoints).       *       * \param addr The physical address (device, instance) of the stream endpoint       * \return The allocated EPID       */      sep_id_t allocate_epid(const sep_addr_t& addr); +    /*! \brief Allocate an EPID for the specified endpoint. +     * Also initialize the specified endpoint. +     * +     * \param addr The physical address (device, instance) of the stream endpoint +     * \param mgmt_portal The management portal to use for initializing the SEP/EPID +     * \param chdr_ctrl_xport The ctrl xport to use for initializing the SEP/EPID +     * \return The allocated EPID +     */ +    sep_id_t allocate_epid(const sep_addr_t& addr, mgmt::mgmt_portal& mgmt_portal, +        chdr_ctrl_xport& xport); +      /*! \brief Get a pre-allocated EPID. Throws an exception is not allocated       *       * \param addr The physical address (device, instance) of the stream endpoint diff --git a/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp b/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp index 850cee460..9251634bd 100644 --- a/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp +++ b/host/lib/include/uhdlib/rfnoc/mgmt_portal.hpp @@ -8,6 +8,7 @@  #define INCLUDED_LIBUHD_MGMT_PORTAL_HPP  #include <uhdlib/rfnoc/chdr_ctrl_xport.hpp> +#include <uhdlib/rfnoc/chdr_packet.hpp>  #include <uhdlib/rfnoc/chdr_types.hpp>  #include <memory>  #include <set> @@ -55,6 +56,8 @@ public:      //! Initialize a stream endpoint and assign an endpoint ID to it      // +    // This should only be called by the epid_allocator +    //      // \param xport The host stream endpoint's CTRL transport      // \param addr The physical address of the stream endpoint      // \param epid The endpoint ID to assign to this endpoint @@ -62,11 +65,21 @@ public:      virtual void initialize_endpoint(          chdr_ctrl_xport& xport, const sep_addr_t& addr, const sep_id_t& epid) = 0; +    //! Register an already-initialized stream endpoint's endpoint ID +    // +    // This should only be called by the epid_allocator +    // +    // \param addr The physical address of the stream endpoint +    // \param epid The endpoint ID to assign to this endpoint +    // +    virtual void register_endpoint( +        const sep_addr_t& addr, const sep_id_t& epid) = 0; +      //! Get information about a discovered (reachable) stream endpoint      //      // \param epid The endpoint ID of the endpoint to lookup      // -    virtual bool is_endpoint_initialized(const sep_id_t& epid) const = 0; +    virtual bool is_endpoint_registered(const sep_id_t& epid) const = 0;      //! Get information about a discovered (reachable) stream endpoint      // diff --git a/host/lib/rfnoc/epid_allocator.cpp b/host/lib/rfnoc/epid_allocator.cpp index 97a30dc64..60544eb58 100644 --- a/host/lib/rfnoc/epid_allocator.cpp +++ b/host/lib/rfnoc/epid_allocator.cpp @@ -12,7 +12,6 @@ using namespace uhd::rfnoc;  epid_allocator::epid_allocator(sep_id_t start_epid) : _next_epid(start_epid) {} -  sep_id_t epid_allocator::allocate_epid(const sep_addr_t& addr)  {      std::lock_guard<std::mutex> lock(_mutex); @@ -27,6 +26,24 @@ sep_id_t epid_allocator::allocate_epid(const sep_addr_t& addr)      }  } +sep_id_t epid_allocator::allocate_epid( +    const sep_addr_t& addr, mgmt::mgmt_portal& mgmt_portal, chdr_ctrl_xport& xport) +{ +    std::lock_guard<std::mutex> lock(_mutex); + +    if (_epid_map.count(addr) == 0) { +        sep_id_t new_epid   = _next_epid++; +        _epid_map[addr]     = new_epid; +        _addr_map[new_epid] = addr; +        mgmt_portal.initialize_endpoint(xport, addr, new_epid); +        return new_epid; +    } else { +        sep_id_t epid = _epid_map.at(addr); +        mgmt_portal.register_endpoint(addr, epid); +        return epid; +    } +} +  sep_id_t epid_allocator::get_epid(const sep_addr_t& addr)  {      std::lock_guard<std::mutex> lock(_mutex); diff --git a/host/lib/rfnoc/link_stream_manager.cpp b/host/lib/rfnoc/link_stream_manager.cpp index b0e864347..a85ad2b4b 100644 --- a/host/lib/rfnoc/link_stream_manager.cpp +++ b/host/lib/rfnoc/link_stream_manager.cpp @@ -98,7 +98,8 @@ public:          _ensure_ep_is_reachable(dst_addr);          // Allocate EPIDs -        sep_id_t dst_epid = _epid_alloc->allocate_epid(dst_addr); +        sep_id_t dst_epid = _epid_alloc->allocate_epid(dst_addr, *_mgmt_portal, +            *_ctrl_xport);          // Make sure that the software side of the endpoint is initialized and reachable          if (_ctrl_ep == nullptr) { @@ -108,7 +109,6 @@ public:          }          // Setup a route to the EPID -        _mgmt_portal->initialize_endpoint(*_ctrl_xport, dst_addr, dst_epid);          _mgmt_portal->setup_local_route(*_ctrl_xport, dst_epid);          if (!_mgmt_portal->get_endpoint_info(dst_epid).has_ctrl) {              throw uhd::rfnoc_error( @@ -129,14 +129,13 @@ public:          _ensure_ep_is_reachable(dst_addr);          _ensure_ep_is_reachable(src_addr); -        // Allocate EPIDs -        sep_id_t dst_epid = _epid_alloc->allocate_epid(dst_addr); -        sep_id_t src_epid = _epid_alloc->allocate_epid(src_addr); - -        // Initialize endpoints -        _mgmt_portal->initialize_endpoint(*_ctrl_xport, dst_addr, dst_epid); -        _mgmt_portal->initialize_endpoint(*_ctrl_xport, src_addr, src_epid); +        // Allocate EPIDs and initialize endpoints +        sep_id_t dst_epid = _epid_alloc->allocate_epid(dst_addr, *_mgmt_portal, +            *_ctrl_xport); +        sep_id_t src_epid = _epid_alloc->allocate_epid(src_addr, *_mgmt_portal, +            *_ctrl_xport); +        // Set up routes          _mgmt_portal->setup_remote_route(*_ctrl_xport, dst_epid, src_epid);          return sep_id_pair_t(src_epid, dst_epid); @@ -221,8 +220,8 @@ public:          _ensure_ep_is_reachable(dst_addr);          // Generate a new destination (device) EPID instance -        sep_id_t dst_epid = _epid_alloc->allocate_epid(dst_addr); -        _mgmt_portal->initialize_endpoint(*_ctrl_xport, dst_addr, dst_epid); +        sep_id_t dst_epid = _epid_alloc->allocate_epid(dst_addr, *_mgmt_portal, +            *_ctrl_xport);          if (!_mgmt_portal->get_endpoint_info(dst_epid).has_data) {              throw uhd::rfnoc_error("Downstream endpoint does not support data traffic"); @@ -250,8 +249,8 @@ public:          _ensure_ep_is_reachable(src_addr);          // Generate a new source (device) EPID instance -        sep_id_t src_epid = _epid_alloc->allocate_epid(src_addr); -        _mgmt_portal->initialize_endpoint(*_ctrl_xport, src_addr, src_epid); +        sep_id_t src_epid = _epid_alloc->allocate_epid(src_addr, *_mgmt_portal, +            *_ctrl_xport);          if (!_mgmt_portal->get_endpoint_info(src_epid).has_data) {              throw uhd::rfnoc_error("Downstream endpoint does not support data traffic"); diff --git a/host/lib/rfnoc/mgmt_portal.cpp b/host/lib/rfnoc/mgmt_portal.cpp index ed3e754a2..0e0997a36 100644 --- a/host/lib/rfnoc/mgmt_portal.cpp +++ b/host/lib/rfnoc/mgmt_portal.cpp @@ -207,6 +207,7 @@ public:          chdr_ctrl_xport& xport, const sep_addr_t& addr, const sep_id_t& epid)      {          std::lock_guard<std::recursive_mutex> lock(_mutex); +          auto my_epid = xport.get_epid();          // Create a node ID from lookup info @@ -216,9 +217,6 @@ public:                  "initialize_endpoint(): Cannot reach node with specified address.");          }          const node_addr_t& node_addr = _node_addr_map.at(lookup_node); -        if (is_endpoint_initialized(epid)) { -            return; -        }          // Build a management transaction to first get to the node          mgmt_payload cfg_xact; @@ -236,7 +234,22 @@ public:          // Send the transaction and receive a response.          // We don't care about the contents of the response.          _send_recv_mgmt_transaction(xport, cfg_xact); +        register_endpoint(addr, epid); +    } +    virtual void register_endpoint(const sep_addr_t& addr, const sep_id_t& epid) +    { +        std::lock_guard<std::recursive_mutex> lock(_mutex); +        if (is_endpoint_registered(epid)) { +            return; +        } +        // Create a node ID from lookup info +        node_id_t lookup_node(addr.first, NODE_TYPE_STRM_EP, addr.second); +        if (_node_addr_map.count(lookup_node) == 0) { +            throw uhd::lookup_error( +                "initialize_endpoint(): Cannot reach node with specified address."); +        } +        const node_addr_t& node_addr = _node_addr_map.at(lookup_node);          // Add/update the entry in the stream endpoint ID map          _epid_addr_map[epid] = addr;          UHD_LOG_DEBUG("RFNOC::MGMT", @@ -248,7 +261,7 @@ public:                  % epid % to_string(node_addr)));      } -    virtual bool is_endpoint_initialized(const sep_id_t& epid) const +    virtual bool is_endpoint_registered(const sep_id_t& epid) const      {          std::lock_guard<std::recursive_mutex> lock(_mutex);          return (_epid_addr_map.count(epid) > 0); @@ -405,13 +418,13 @@ public:      {          std::lock_guard<std::recursive_mutex> lock(_mutex); -        if (not is_endpoint_initialized(dst_epid)) { +        if (not is_endpoint_registered(dst_epid)) {              throw uhd::routing_error("Route setup failed. The destination endpoint was " -                                     "not initialized and bound to an EPID"); +                                     "not bound to an EPID and registered");          } -        if (not is_endpoint_initialized(src_epid)) { +        if (not is_endpoint_registered(src_epid)) {              throw uhd::routing_error("Route setup failed. The source endpoint was " -                                     "not initialized and bound to an EPID"); +                                     "not bound to an EPID and registered");          }          if (not can_remote_route( @@ -1065,7 +1078,7 @@ private: // Members      // A list of all discovered endpoints      std::set<sep_addr_t> _discovered_ep_set;      // A table that maps a stream endpoint ID to the physical address of the stream -    // endpoint +    // endpoint. This is a cache of the values from the epid_allocator      std::map<sep_id_t, sep_addr_t> _epid_addr_map;      // Send/recv transports      size_t _send_seqnum;  | 
