aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_eth_mgr.hpp
blob: 1f4013e1732e2fbf915328f4de6ebe3798702c45 (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 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#ifndef INCLUDED_X300_ETH_MGR_HPP
#define INCLUDED_X300_ETH_MGR_HPP

#include "x300_conn_mgr.hpp"
#include "x300_device_args.hpp"
#include "x300_mboard_type.hpp"
#include <uhd/property_tree.hpp>
#include <uhd/transport/if_addrs.hpp>
#include <uhd/transport/udp_constants.hpp>
#include <uhd/transport/udp_simple.hpp> //mtu
#include <uhd/types/device_addr.hpp>
#include <uhd/types/direction.hpp>
#include <functional>
#include <map>
#include <vector>

namespace uhd { namespace usrp { namespace x300 {

/*! Helper class to manage the eth connections
 */
class eth_manager : public conn_manager
{
public:
    eth_manager(const x300_device_args_t& args,
        uhd::property_tree::sptr tree,
        const uhd::fs_path& root_path);

    //! Return the motherboard type using eth
    static x300_mboard_t get_mb_type_from_eth(
        const std::string& resource, const std::string& rpc_port);

    static uhd::device_addrs_t find(const uhd::device_addr_t& hint);

    /*! Return a reference to a ZPU ctrl interface object
     */
    uhd::wb_iface::sptr get_ctrl_iface();

    void init_link(
        const mboard_eeprom_t& mb_eeprom, const std::string& loaded_fpga_image);

    size_t get_mtu(uhd::direction_t dir);

    /*! Safely release a ZPU control object
     *
     * This embeds the release call (provided by \p release_fn) within a safe
     * context to avoid multiple accesses to the eth bus.
     */
    void release_ctrl_iface(std::function<void(void)>&& release_fn);

    /*! Return the list of local device IDs associated with this link
     *
     * Note: this will only be valid after init_link() is called.
     */
    std::vector<uhd::rfnoc::device_id_t> get_local_device_ids()
    {
        return _local_device_ids;
    }

    uhd::transport::both_links_t get_links(uhd::transport::link_type_t link_type,
        const uhd::rfnoc::device_id_t local_device_id,
        const uhd::rfnoc::sep_id_t& local_epid,
        const uhd::rfnoc::sep_id_t& remote_epid,
        const uhd::device_addr_t& link_args);

private:
    //! Function to create a udp_simple::sptr (kernel-based or DPDK-based)
    using udp_simple_factory_t = std::function<uhd::transport::udp_simple::sptr(
        const std::string&, const std::string&)>;

    // Ethernet ports
    enum x300_eth_iface_t {
        X300_IFACE_NONE = 0,
        X300_IFACE_ETH0 = 1,
        X300_IFACE_ETH1 = 2,
    };

    struct x300_eth_conn_t
    {
        std::string addr;
        x300_eth_iface_t type;
        size_t link_rate;
    };

    struct frame_size_t
    {
        size_t recv_frame_size;
        size_t send_frame_size;
    };

    // Get the primary ethernet connection
    inline const x300_eth_conn_t& get_pri_eth() const
    {
        return eth_conns.at(_local_device_ids.at(0));
    }

    static udp_simple_factory_t x300_get_udp_factory(const device_addr_t& args);

    /*!
     * Automatically determine the maximum frame size available by sending a UDP packet
     * to the device and see which packet sizes actually work. This way, we can take
     * switches etc. into account which might live between the device and the host.
     */
    frame_size_t determine_max_frame_size(
        const std::string& addr, const frame_size_t& user_mtu);

    // Discover the ethernet connections per motherboard
    void discover_eth(
        const uhd::usrp::mboard_eeprom_t mb_eeprom, const std::string& loaded_fpga_image);


    const x300_device_args_t _args;

    uhd::property_tree::sptr _tree;

    udp_simple_factory_t _x300_make_udp_connected;

    std::map<uhd::rfnoc::device_id_t, x300_eth_conn_t> eth_conns;

    frame_size_t _max_frame_sizes;

    uhd::device_addr_t recv_args;
    uhd::device_addr_t send_args;

    std::vector<uhd::rfnoc::device_id_t> _local_device_ids;
};

}}} // namespace uhd::usrp::x300

#endif /* INCLUDED_X300_ETH_MGR_HPP */