aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/mpmd/mpmd_xport_ctrl_liberio.cpp
blob: 2780f15da00babc1bea65b39e51491f9ef393a77 (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//
// Copyright 2017 Ettus Research, National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0
//

#include "mpmd_xport_ctrl_liberio.hpp"
#include "../transport/liberio_zero_copy.hpp"
#include <uhd/transport/udp_zero_copy.hpp>
#include <uhd/utils/byteswap.hpp>

using namespace uhd;
using namespace uhd::mpmd::xport;

namespace {

    uint32_t extract_sid_from_pkt(void* pkt, size_t) {
        return uhd::sid_t(uhd::wtohx(static_cast<const uint32_t*>(pkt)[1]))
            .get_dst();
    }

}

mpmd_xport_ctrl_liberio::mpmd_xport_ctrl_liberio(
        const uhd::device_addr_t& mb_args
) : _mb_args(mb_args)
  , _recv_args(filter_args(mb_args, "recv"))
  , _send_args(filter_args(mb_args, "send"))
{
    // nop
}


uhd::both_xports_t
mpmd_xport_ctrl_liberio::make_transport(
        mpmd_xport_mgr::xport_info_t &xport_info,
        const usrp::device3_impl::xport_type_t xport_type,
        const uhd::device_addr_t& /*xport_args_*/
) {
    transport::zero_copy_xport_params default_buff_args;
    /* default ones for RX / TX, override below */

    default_buff_args.send_frame_size = get_mtu(uhd::TX_DIRECTION);
    default_buff_args.recv_frame_size = get_mtu(uhd::RX_DIRECTION);
    default_buff_args.num_recv_frames = 128;
    default_buff_args.num_send_frames = 128;

    if (xport_type == usrp::device3_impl::CTRL) {
      default_buff_args.send_frame_size = 128;
      default_buff_args.recv_frame_size = 128;
    } else if (xport_type == usrp::device3_impl::ASYNC_MSG) {
      default_buff_args.send_frame_size = 256;
      default_buff_args.recv_frame_size = 256;
    } else if (xport_type == usrp::device3_impl::RX_DATA) {
      default_buff_args.send_frame_size = 64;
    } else {
      default_buff_args.recv_frame_size = 64;
    }

    const std::string tx_dev = xport_info["tx_dev"];
    const std::string rx_dev = xport_info["rx_dev"];

    both_xports_t xports;
    xports.endianness = uhd::ENDIANNESS_LITTLE;
    xports.send_sid = sid_t(xport_info["send_sid"]);
    xports.recv_sid = xports.send_sid.reversed();

    // this is kinda ghetto: scale buffer for muxed xports since we share the
    // buffer...
    float divisor = 1;
    if (xport_type == usrp::device3_impl::CTRL)
      divisor = 16;
    else if (xport_type == usrp::device3_impl::ASYNC_MSG)
      divisor = 4;


    //if (xport_info["muxed"] == "True") {
    //// FIXME tbw
    //}
    if (xport_type == usrp::device3_impl::CTRL) {
        UHD_ASSERT_THROW(xport_info["muxed"] == "True");
        if (not _ctrl_dma_xport) {
            default_buff_args.send_frame_size = 128;
            default_buff_args.recv_frame_size = 128;
            _ctrl_dma_xport = make_muxed_liberio_xport(tx_dev, rx_dev,
                    default_buff_args, int(divisor));
        }

        UHD_LOGGER_TRACE("MPMD")
            << "Making (muxed) stream with num " << xports.recv_sid.get_dst();
        xports.recv = _ctrl_dma_xport->make_stream(xports.recv_sid.get_dst());
    } else if (xport_type == usrp::device3_impl::ASYNC_MSG) {
        UHD_ASSERT_THROW(xport_info["muxed"] == "True");
        if (not _async_msg_dma_xport) {
            default_buff_args.send_frame_size = 256;
            default_buff_args.recv_frame_size = 256;
            _async_msg_dma_xport = make_muxed_liberio_xport(
                    tx_dev, rx_dev, default_buff_args, int(divisor));
        }

        UHD_LOGGER_TRACE("MPMD")
            << "making (muxed) stream with num " << xports.recv_sid.get_dst();
        xports.recv =
            _async_msg_dma_xport->make_stream(xports.recv_sid.get_dst());
    } else {
        xports.recv =
            transport::liberio_zero_copy::make(
                    tx_dev, rx_dev, default_buff_args);
    }

    transport::udp_zero_copy::buff_params buff_params;
    buff_params.recv_buff_size =
        float(default_buff_args.recv_frame_size) *
        float(default_buff_args.num_recv_frames) / divisor;
    buff_params.send_buff_size =
        float(default_buff_args.send_frame_size) *
        float(default_buff_args.num_send_frames) / divisor;


    // Finish both_xports_t object and return:
    xports.recv_buff_size = buff_params.recv_buff_size;
    xports.send_buff_size = buff_params.send_buff_size;
    xports.send = xports.recv;
    return xports;
}

bool mpmd_xport_ctrl_liberio::is_valid(
    const mpmd_xport_mgr::xport_info_t& xport_info
) const {
    return xport_info.at("type") == "liberio";
}

size_t mpmd_xport_ctrl_liberio::get_mtu(
    const uhd::direction_t /* dir */
) const {
    return 2 * getpagesize();
}

uhd::transport::muxed_zero_copy_if::sptr
mpmd_xport_ctrl_liberio::make_muxed_liberio_xport(
        const std::string &tx_dev,
        const std::string &rx_dev,
        const uhd::transport::zero_copy_xport_params &buff_args,
        const size_t max_muxed_ports
) {
    auto base_xport = transport::liberio_zero_copy::make(
            tx_dev, rx_dev, buff_args);

    return uhd::transport::muxed_zero_copy_if::make(
            base_xport, extract_sid_from_pkt, max_muxed_ports);
}