aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/mpmd/mpmd_link_if_mgr.cpp
blob: 6bb6cae3abc0489c7ffcb4dc9e15286eb36accc7 (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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// Copyright 2017 Ettus Research, National Instruments Company
// Copyright 2019 Ettus Research, National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#include "mpmd_link_if_mgr.hpp"
#include "mpmd_impl.hpp"
#include "mpmd_link_if_ctrl_base.hpp"
#include "mpmd_link_if_ctrl_udp.hpp"
#ifdef HAVE_LIBERIO
#    include "mpmd_link_if_ctrl_liberio.hpp"
#endif
#ifdef HAVE_DPDK
#    include "mpmd_link_if_ctrl_dpdk_udp.hpp"
#endif

uhd::dict<std::string, std::string> uhd::mpmd::xport::filter_args(
    const uhd::device_addr_t& args, const std::string& prefix)
{
    uhd::dict<std::string, std::string> filtered_args;
    for (const std::string& key : args.keys()) {
        if (key.find(prefix) != std::string::npos) {
            filtered_args[key] = args[key];
        }
    }

    return filtered_args;
}

using namespace uhd::mpmd::xport;

class mpmd_link_if_mgr_impl : public mpmd_link_if_mgr
{
public:
    mpmd_link_if_mgr_impl(const uhd::device_addr_t& mb_args) : _mb_args(mb_args) {}

    /**************************************************************************
     * API (see mpmd_link_if_mgr.hpp)
     *************************************************************************/
    bool connect(const std::string& link_type, const xport_info_list_t& xport_info)
    {
        auto link_if_ctrl = make_link_if_ctrl(link_type, xport_info);
        if (!link_if_ctrl) {
            UHD_LOG_WARNING(
                "MPMD::XPORT", "Unable to create xport ctrl for link type " << link_type);
            return false;
        }
        if (link_if_ctrl->get_num_links() == 0) {
            UHD_LOG_TRACE("MPMD::XPORT",
                "Link type " << link_type
                             << " has no valid links in this configuration.");
            return false;
        }
        const size_t xport_idx = _link_if_ctrls.size();
        for (size_t link_idx = 0; link_idx < link_if_ctrl->get_num_links(); link_idx++) {
            _link_link_if_ctrl_map.push_back(std::make_pair(xport_idx, link_idx));
        }
        _link_if_ctrls.push_back(std::move(link_if_ctrl));
        return true;
    }

    size_t get_num_links()
    {
        return _link_link_if_ctrl_map.size();
    }

    uhd::transport::both_links_t get_link(const size_t link_idx,
        const uhd::transport::link_type_t link_type,
        const uhd::device_addr_t& link_args)
    {
        const size_t link_if_ctrl_idx = _link_link_if_ctrl_map.at(link_idx).first;
        const size_t xport_link_idx   = _link_link_if_ctrl_map.at(link_idx).second;
        return _link_if_ctrls.at(link_if_ctrl_idx)
            ->get_link(xport_link_idx, link_type, link_args);
    }

    size_t get_mtu(const size_t link_idx, const uhd::direction_t dir) const
    {
        return _link_if_ctrls.at(_link_link_if_ctrl_map.at(link_idx).first)->get_mtu(dir);
    }

    const uhd::rfnoc::chdr::chdr_packet_factory& get_packet_factory(
        const size_t link_idx) const
    {
        const size_t link_if_ctrl_idx = _link_link_if_ctrl_map.at(link_idx).first;
        return _link_if_ctrls.at(link_if_ctrl_idx)->get_packet_factory();
    }

private:
    /**************************************************************************
     * Private methods / helpers
     *************************************************************************/
    mpmd_link_if_ctrl_base::uptr make_link_if_ctrl(
        const std::string& link_type, const xport_info_list_t& xport_info)
    {
        // Here, we hard-code the list of available transport types
        if (link_type == "udp") {
#ifdef HAVE_DPDK
            // if (_mb_args.has_key("use_dpdk")) {
            //    return std::make_unique<mpmd_link_if_ctrl_dpdk_udp>(_mb_args,
            //    xport_info);
            //}
#endif
            return std::make_unique<mpmd_link_if_ctrl_udp>(_mb_args, xport_info);
#ifdef HAVE_LIBERIO
        } else if (link_type == "liberio") {
            return std::make_unique<mpmd_link_if_ctrl_liberio>(_mb_args, xport_info);
#endif
        }
        UHD_LOG_WARNING("MPMD", "Cannot instantiate transport medium " << link_type);
        return nullptr;
    }

    /**************************************************************************
     * Private attributes
     *************************************************************************/
    //! Cache available xport manager implementations
    //
    // Should only every be populated by connect()
    std::vector<mpmd_link_if_ctrl_base::uptr> _link_if_ctrls;
    // Maps link index to link_if_ctrl index. To look up the xport ctrl for link
    // number L, do something like this:
    // auto& link_if_ctrl = _link_if_ctrls.at(_link_link_if_ctrl_map.at(L).first);
    std::vector<std::pair<size_t, size_t>> _link_link_if_ctrl_map;

    //! Motherboard args, can contain things like 'recv_buff_size'
    const uhd::device_addr_t _mb_args;
};

mpmd_link_if_mgr::uptr mpmd_link_if_mgr::make(const uhd::device_addr_t& mb_args)
{
    return std::make_unique<mpmd_link_if_mgr_impl>(mb_args);
}