aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2014-02-14 12:05:07 -0800
committerBen Hilburn <ben.hilburn@ettus.com>2014-02-14 12:05:07 -0800
commitff1546f8137f7f92bb250f685561b0c34cc0e053 (patch)
tree7fa6fd05c8828df256a1b20e2935bd3ba9899e2c /host/lib/usrp/x300
parent4f691d88123784c2b405816925f1a1aef69d18c1 (diff)
downloaduhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.tar.gz
uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.tar.bz2
uhd-ff1546f8137f7f92bb250f685561b0c34cc0e053.zip
Pushing the bulk of UHD-3.7.0 code.
Diffstat (limited to 'host/lib/usrp/x300')
-rw-r--r--host/lib/usrp/x300/x300_clock_ctrl.cpp6
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp275
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp51
3 files changed, 224 insertions, 108 deletions
diff --git a/host/lib/usrp/x300/x300_clock_ctrl.cpp b/host/lib/usrp/x300/x300_clock_ctrl.cpp
index 1a4cd4668..a986928a7 100644
--- a/host/lib/usrp/x300/x300_clock_ctrl.cpp
+++ b/host/lib/usrp/x300/x300_clock_ctrl.cpp
@@ -24,6 +24,8 @@
#include <cmath>
#include <cstdlib>
+static const double X300_REF_CLK_OUT_RATE = 10e6;
+
using namespace uhd;
class x300_clock_ctrl_impl : public x300_clock_ctrl {
@@ -66,7 +68,7 @@ double get_sysref_clock_rate(void) {
double get_refout_clock_rate(void) {
//We support only one reference output rate
- return 10e6;
+ return X300_REF_CLK_OUT_RATE;
}
void set_dboard_rate(const x300_clock_which_t, double rate) {
@@ -292,7 +294,7 @@ void set_master_clock_rate(double clock_rate) {
_lmk04816_regs.CLKout8_9_DIV = vco_div;
// Register 5
_lmk04816_regs.CLKout10_11_PD = lmk04816_regs_t::CLKOUT10_11_PD_NORMAL;
- _lmk04816_regs.CLKout10_11_DIV = vco_div;
+ _lmk04816_regs.CLKout10_11_DIV = vco_div * static_cast<int>(clock_rate/X300_REF_CLK_OUT_RATE);
// Register 6
_lmk04816_regs.CLKout0_TYPE = lmk04816_regs_t::CLKOUT0_TYPE_LVDS; //FPGA
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index f62967018..b20897fc6 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -34,6 +34,7 @@
#include <boost/assign/list_of.hpp>
#include <fstream>
#include <uhd/transport/udp_zero_copy.hpp>
+#include <uhd/transport/udp_constants.hpp>
#include <uhd/transport/nirio_zero_copy.hpp>
#include <uhd/transport/nirio/niusrprio_session.h>
#include <uhd/utils/platform.hpp>
@@ -399,34 +400,25 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
if (key.find("send") != std::string::npos) mb.send_args[key] = dev_addr[key];
}
- const std::vector<std::string> DB_NAMES = boost::assign::list_of("A")("B");
-
- //create basic communication
- UHD_MSG(status) << "Setup basic communication..." << std::endl;
- if (mb.xport_path == "nirio") {
- mb.zpu_ctrl = x300_make_ctrl_iface_pcie(mb.rio_fpga_interface->get_kernel_proxy());
- } else {
- mb.zpu_ctrl = x300_make_ctrl_iface_enet(udp_simple::make_connected(mb.addr,
- BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)));
- }
-
- if (mb.xport_path == "eth")
- {
- mtu_result_t user_set;
- user_set.recv_mtu = dev_addr.has_key("recv_frame_size") \
- ? boost::lexical_cast<size_t>(dev_addr["recv_frame_size"]) \
- : X300_ETH_DATA_FRAME_SIZE;
- user_set.send_mtu = dev_addr.has_key("send_frame_size") \
- ? boost::lexical_cast<size_t>(dev_addr["send_frame_size"]) \
- : X300_ETH_DATA_FRAME_SIZE;
-
- // Detect the MTU on the path to the USRP
- mtu_result_t result;
- try {
- result = determine_mtu(mb.addr, user_set);
- } catch(std::exception &e) {
- UHD_MSG(error) << e.what() << std::endl;
- }
+ if (mb.xport_path == "eth" ) {
+ /* This is an ETH connection. Figure out what the maximum supported frame
+ * size is for the transport in the up and down directions. The frame size
+ * depends on the host PIC's NIC's MTU settings. To determine the frame size,
+ * we test for support up to an expected "ceiling". If the user
+ * specified a frame size, we use that frame size as the ceiling. If no
+ * frame size was specified, we use the maximum UHD frame size.
+ *
+ * To optimize performance, the frame size should be greater than or equal
+ * to the frame size that UHD uses so that frames don't get split across
+ * multiple transmission units - this is why the limits passed into the
+ * 'determine_max_frame_size' function are actually frame sizes. */
+ frame_size_t req_max_frame_size;
+ req_max_frame_size.recv_frame_size = (mb.recv_args.has_key("recv_frame_size")) \
+ ? boost::lexical_cast<size_t>(mb.recv_args["recv_frame_size"]) \
+ : X300_10GE_DATA_FRAME_MAX_SIZE;
+ req_max_frame_size.send_frame_size = (mb.send_args.has_key("send_frame_size")) \
+ ? boost::lexical_cast<size_t>(mb.send_args["send_frame_size"]) \
+ : X300_10GE_DATA_FRAME_MAX_SIZE;
#if defined UHD_PLATFORM_LINUX
const std::string mtu_tool("ip link");
@@ -436,23 +428,47 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
const std::string mtu_tool("ifconfig");
#endif
- if(result.recv_mtu < user_set.recv_mtu) {
+ // Detect the frame size on the path to the USRP
+ try {
+ max_frame_sizes = determine_max_frame_size(mb.addr, req_max_frame_size);
+ } catch(std::exception &e) {
+ UHD_MSG(error) << e.what() << std::endl;
+ }
+
+ if ((mb.recv_args.has_key("recv_frame_size"))
+ && (req_max_frame_size.recv_frame_size < max_frame_sizes.recv_frame_size)) {
UHD_MSG(warning)
- << boost::format("The receive path contains entities that do not support MTUs >= one recv frame's size (%lu).")
- % user_set.recv_mtu << std::endl
- << boost::format("Please verify your NIC's MTU setting using '%s' or set the recv_frame_size argument.")
- % mtu_tool << std::endl;
+ << boost::format("You requested a receive frame size of (%lu) but your NIC's max frame size is (%lu).")
+ % req_max_frame_size.recv_frame_size << max_frame_sizes.recv_frame_size << std::endl
+ << boost::format("Please verify your NIC's MTU setting using '%s' or set the recv_frame_size argument appropriately.")
+ % mtu_tool << std::endl
+ << "UHD will use the auto-detected max frame size for this connection."
+ << std::endl;
}
- if(result.send_mtu < user_set.send_mtu) {
+ if ((mb.recv_args.has_key("send_frame_size"))
+ && (req_max_frame_size.send_frame_size < max_frame_sizes.send_frame_size)) {
UHD_MSG(warning)
- << boost::format("The send path contains entities that do not support MTUs >= one send frame's size (%lu).")
- % user_set.send_mtu << std::endl
- << boost::format("Please verify your NIC's MTU setting using '%s' or set the send_frame_size argument.")
- % mtu_tool << std::endl;
+ << boost::format("You requested a send frame size of (%lu) but your NIC's max frame size is (%lu).")
+ % req_max_frame_size.send_frame_size << max_frame_sizes.send_frame_size << std::endl
+ << boost::format("Please verify your NIC's MTU setting using '%s' or set the send_frame_size argument appropriately.")
+ % mtu_tool << std::endl
+ << "UHD will use the auto-detected max frame size for this connection."
+ << std::endl;
}
}
+ const std::vector<std::string> DB_NAMES = boost::assign::list_of("A")("B");
+
+ //create basic communication
+ UHD_MSG(status) << "Setup basic communication..." << std::endl;
+ if (mb.xport_path == "nirio") {
+ mb.zpu_ctrl = x300_make_ctrl_iface_pcie(mb.rio_fpga_interface->get_kernel_proxy());
+ } else {
+ mb.zpu_ctrl = x300_make_ctrl_iface_enet(udp_simple::make_connected(mb.addr,
+ BOOST_STRINGIZE(X300_FW_COMMS_UDP_PORT)));
+ }
+
mb.claimer_task = uhd::task::make(boost::bind(&x300_impl::claimer_loop, this, mb.zpu_ctrl));
//extract the FW path for the X300
@@ -469,6 +485,9 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
this->check_fw_compat(mb_path, mb.zpu_ctrl);
this->check_fpga_compat(mb_path, mb.zpu_ctrl);
+ //store which FPGA image is loaded
+ mb.loaded_fpga_image = get_fpga_option(mb.zpu_ctrl);
+
//low speed perif access
mb.zpu_spi = spi_core_3000::make(mb.zpu_ctrl, SR_ADDR(SET0_BASE, ZPU_SR_SPI),
SR_ADDR(SET0_BASE, ZPU_RB_SPI));
@@ -1030,8 +1049,6 @@ x300_impl::both_xports_t x300_impl::make_transport(
)
{
mboard_members_t &mb = _mb[mb_index];
- const std::string& addr = mb.addr;
- const std::string& xport_path = mb.xport_path;
both_xports_t xports;
sid_config_t config;
@@ -1047,47 +1064,122 @@ x300_impl::both_xports_t x300_impl::make_transport(
(prefix != X300_RADIO_DEST_PREFIX_CTRL) ? args : DEFAULT_XPORT_ARGS;
zero_copy_xport_params default_buff_args;
- if (xport_path == "nirio") {
+
+ if (mb.xport_path == "nirio") {
default_buff_args.send_frame_size =
- (prefix == X300_RADIO_DEST_PREFIX_TX) ? X300_PCIE_DATA_FRAME_SIZE : X300_PCIE_MSG_FRAME_SIZE;
+ (prefix == X300_RADIO_DEST_PREFIX_TX)
+ ? X300_PCIE_DATA_FRAME_SIZE
+ : X300_PCIE_MSG_FRAME_SIZE;
+
default_buff_args.recv_frame_size =
- (prefix == X300_RADIO_DEST_PREFIX_RX) ? X300_PCIE_DATA_FRAME_SIZE : X300_PCIE_MSG_FRAME_SIZE;
+ (prefix == X300_RADIO_DEST_PREFIX_RX)
+ ? X300_PCIE_DATA_FRAME_SIZE
+ : X300_PCIE_MSG_FRAME_SIZE;
+
default_buff_args.num_send_frames =
- (prefix == X300_RADIO_DEST_PREFIX_TX) ? X300_PCIE_DATA_NUM_FRAMES : X300_PCIE_MSG_NUM_FRAMES;
+ (prefix == X300_RADIO_DEST_PREFIX_TX)
+ ? X300_PCIE_DATA_NUM_FRAMES
+ : X300_PCIE_MSG_NUM_FRAMES;
+
default_buff_args.num_recv_frames =
- (prefix == X300_RADIO_DEST_PREFIX_RX) ? X300_PCIE_DATA_NUM_FRAMES : X300_PCIE_MSG_NUM_FRAMES;
+ (prefix == X300_RADIO_DEST_PREFIX_RX)
+ ? X300_PCIE_DATA_NUM_FRAMES
+ : X300_PCIE_MSG_NUM_FRAMES;
xports.recv = nirio_zero_copy::make(
- mb.rio_fpga_interface, get_pcie_dma_channel(destination, prefix), default_buff_args, xport_args);
+ mb.rio_fpga_interface,
+ get_pcie_dma_channel(destination, prefix),
+ default_buff_args,
+ xport_args);
+
xports.send = xports.recv;
//For the nirio transport, buffer size is depends on the frame size and num frames
xports.recv_buff_size = xports.recv->get_num_recv_frames() * xports.recv->get_recv_frame_size();
xports.send_buff_size = xports.send->get_num_send_frames() * xports.send->get_send_frame_size();
- } else {
+ } else if (mb.xport_path == "eth") {
+
+ /* Determine what the recommended frame size is for this
+ * connection type.*/
+ size_t eth_data_rec_frame_size = 0;
+
+ if (mb.loaded_fpga_image == "HGS") {
+ if (mb.router_dst_here == X300_XB_DST_E0) {
+ eth_data_rec_frame_size = X300_1GE_DATA_FRAME_MAX_SIZE;
+ } else if (mb.router_dst_here == X300_XB_DST_E1) {
+ eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE;
+ }
+ } else if (mb.loaded_fpga_image == "XGS") {
+ eth_data_rec_frame_size = X300_10GE_DATA_FRAME_MAX_SIZE;
+ }
+
+ if (eth_data_rec_frame_size == 0) {
+ throw uhd::runtime_error("Unable to determine ETH link type.");
+ }
+
+ /* Print a warning if the system's max available frame size is less than the most optimal
+ * frame size for this type of connection. */
+ if (max_frame_sizes.send_frame_size < eth_data_rec_frame_size) {
+ UHD_MSG(warning)
+ << boost::format("For this connection, UHD recommends a send frame size of at least %lu for best\nperformance, but your system's MTU will only allow %lu.")
+ % eth_data_rec_frame_size
+ % max_frame_sizes.send_frame_size
+ << std::endl
+ << "This will negatively impact your maximum achievable sample rate."
+ << std::endl;
+ }
+
+ if (max_frame_sizes.recv_frame_size < eth_data_rec_frame_size) {
+ UHD_MSG(warning)
+ << boost::format("For this connection, UHD recommends a receive frame size of at least %lu for best\nperformance, but your system's MTU will only allow %lu.")
+ % eth_data_rec_frame_size
+ % max_frame_sizes.recv_frame_size
+ << std::endl
+ << "This will negatively impact your maximum achievable sample rate."
+ << std::endl;
+ }
+
+ // Account for headers
+ size_t system_max_send_frame_size = (size_t) max_frame_sizes.send_frame_size - 64;
+ size_t system_max_recv_frame_size = (size_t) max_frame_sizes.recv_frame_size - 64;
+
+ // Make sure frame sizes do not exceed the max available value supported by UHD
default_buff_args.send_frame_size =
- (prefix == X300_RADIO_DEST_PREFIX_TX) ? X300_ETH_DATA_FRAME_SIZE : X300_ETH_MSG_FRAME_SIZE;
+ (prefix == X300_RADIO_DEST_PREFIX_TX)
+ ? std::min(system_max_send_frame_size, X300_10GE_DATA_FRAME_MAX_SIZE)
+ : std::min(system_max_send_frame_size, X300_ETH_MSG_FRAME_SIZE);
+
default_buff_args.recv_frame_size =
- (prefix == X300_RADIO_DEST_PREFIX_RX) ? X300_ETH_DATA_FRAME_SIZE : X300_ETH_MSG_FRAME_SIZE;
+ (prefix == X300_RADIO_DEST_PREFIX_RX)
+ ? std::min(system_max_recv_frame_size, X300_10GE_DATA_FRAME_MAX_SIZE)
+ : std::min(system_max_recv_frame_size, X300_ETH_MSG_FRAME_SIZE);
+
default_buff_args.num_send_frames =
- (prefix == X300_RADIO_DEST_PREFIX_TX) ? X300_ETH_DATA_NUM_FRAMES : X300_ETH_MSG_NUM_FRAMES;
+ (prefix == X300_RADIO_DEST_PREFIX_TX)
+ ? X300_ETH_DATA_NUM_FRAMES
+ : X300_ETH_MSG_NUM_FRAMES;
+
default_buff_args.num_recv_frames =
- (prefix == X300_RADIO_DEST_PREFIX_RX) ? X300_ETH_DATA_NUM_FRAMES : X300_ETH_MSG_NUM_FRAMES;
+ (prefix == X300_RADIO_DEST_PREFIX_RX)
+ ? X300_ETH_DATA_NUM_FRAMES
+ : X300_ETH_MSG_NUM_FRAMES;
//make a new transport - fpga has no idea how to talk to use on this yet
udp_zero_copy::buff_params buff_params;
- xports.recv = udp_zero_copy::make(addr, BOOST_STRINGIZE(X300_VITA_UDP_PORT), default_buff_args, buff_params, xport_args);
+ xports.recv = udp_zero_copy::make(mb.addr,
+ BOOST_STRINGIZE(X300_VITA_UDP_PORT),
+ default_buff_args,
+ buff_params,
+ xport_args);
+
xports.send = xports.recv;
- //For the UDP transport the buffer size if the size of the socket buffer in the kernel
+ //For the UDP transport the buffer size if the size of the socket buffer
+ //in the kernel
xports.recv_buff_size = buff_params.recv_buff_size;
xports.send_buff_size = buff_params.send_buff_size;
- }
- //always program the framer if this is a socket, even its caching was used
- if (xport_path != "nirio")
- {
//clear the ethernet dispatcher's udp port
//NOT clearing this, the dispatcher is now intelligent
//_zpu_ctrl->poke32(SR_ADDR(SET0_BASE, (ZPU_SR_ETHINT0+8+3)), 0);
@@ -1095,7 +1187,7 @@ x300_impl::both_xports_t x300_impl::make_transport(
//send a mini packet with SID into the ZPU
//ZPU will reprogram the ethernet framer
UHD_LOG << "programming packet for new xport on "
- << addr << std::hex << "sid 0x" << sid << std::dec << std::endl;
+ << mb.addr << std::hex << "sid 0x" << sid << std::dec << std::endl;
//YES, get a __send__ buffer from the __recv__ socket
//-- this is the only way to program the framer for recv:
managed_send_buffer::sptr buff = xports.recv->get_send_buff();
@@ -1113,6 +1205,7 @@ x300_impl::both_xports_t x300_impl::make_transport(
//ethernet framer has been programmed before we return.
mb.zpu_ctrl->peek32(0);
}
+
return xports;
}
@@ -1299,13 +1392,15 @@ bool x300_impl::is_claimed(wb_iface::sptr iface)
}
/***********************************************************************
- * MTU detection
+ * Frame size detection
**********************************************************************/
-x300_impl::mtu_result_t x300_impl::determine_mtu(const std::string &addr, const mtu_result_t &user_mtu)
+x300_impl::frame_size_t x300_impl::determine_max_frame_size(const std::string &addr,
+ const frame_size_t &user_frame_size)
{
- udp_simple::sptr udp = udp_simple::make_connected(addr, BOOST_STRINGIZE(X300_MTU_DETECT_UDP_PORT));
+ udp_simple::sptr udp = udp_simple::make_connected(addr,
+ BOOST_STRINGIZE(X300_MTU_DETECT_UDP_PORT));
- std::vector<boost::uint8_t> buffer(std::max(user_mtu.recv_mtu, user_mtu.send_mtu));
+ std::vector<boost::uint8_t> buffer(std::max(user_frame_size.recv_frame_size, user_frame_size.send_frame_size));
x300_mtu_t *request = reinterpret_cast<x300_mtu_t *>(&buffer.front());
static const double echo_timeout = 0.020; //20 ms
@@ -1317,54 +1412,62 @@ x300_impl::mtu_result_t x300_impl::determine_mtu(const std::string &addr, const
if (!(uhd::ntohx<boost::uint32_t>(request->flags) & X300_MTU_DETECT_ECHO_REPLY))
throw uhd::not_implemented_error("Holler protocol not implemented");
- size_t min_recv_mtu = sizeof(x300_mtu_t);
- size_t max_recv_mtu = user_mtu.recv_mtu;
- size_t min_send_mtu = sizeof(x300_mtu_t);
- size_t max_send_mtu = user_mtu.send_mtu;
+ size_t min_recv_frame_size = sizeof(x300_mtu_t);
+ size_t max_recv_frame_size = user_frame_size.recv_frame_size;
+ size_t min_send_frame_size = sizeof(x300_mtu_t);
+ size_t max_send_frame_size = user_frame_size.send_frame_size;
- UHD_MSG(status) << "Determining receive MTU ... ";
- while (min_recv_mtu < max_recv_mtu)
+ UHD_MSG(status) << "Determining maximum frame size... ";
+ while (min_recv_frame_size < max_recv_frame_size)
{
- size_t test_mtu = (max_recv_mtu/2 + min_recv_mtu/2 + 3) & ~3;
+ size_t test_frame_size = (max_recv_frame_size/2 + min_recv_frame_size/2 + 3) & ~3;
request->flags = uhd::htonx<boost::uint32_t>(X300_MTU_DETECT_ECHO_REQUEST);
- request->size = uhd::htonx<boost::uint32_t>(test_mtu);
+ request->size = uhd::htonx<boost::uint32_t>(test_frame_size);
udp->send(boost::asio::buffer(buffer, sizeof(x300_mtu_t)));
size_t len = udp->recv(boost::asio::buffer(buffer), echo_timeout);
- if (len >= test_mtu)
- min_recv_mtu = test_mtu;
+ if (len >= test_frame_size)
+ min_recv_frame_size = test_frame_size;
else
- max_recv_mtu = test_mtu - 4;
+ max_recv_frame_size = test_frame_size - 4;
+ }
+ if(min_recv_frame_size < IP_PROTOCOL_MIN_MTU_SIZE-IP_PROTOCOL_UDP_PLUS_IP_HEADER) {
+ throw uhd::runtime_error("System receive MTU size is less than the minimum required by the IP protocol.");
}
- UHD_MSG(status) << min_recv_mtu << std::endl;
- UHD_MSG(status) << "Determining send MTU ... ";
- while (min_send_mtu < max_send_mtu)
+ while (min_send_frame_size < max_send_frame_size)
{
- size_t test_mtu = (max_send_mtu/2 + min_send_mtu/2 + 3) & ~3;
+ size_t test_frame_size = (max_send_frame_size/2 + min_send_frame_size/2 + 3) & ~3;
request->flags = uhd::htonx<boost::uint32_t>(X300_MTU_DETECT_ECHO_REQUEST);
request->size = uhd::htonx<boost::uint32_t>(sizeof(x300_mtu_t));
- udp->send(boost::asio::buffer(buffer, test_mtu));
+ udp->send(boost::asio::buffer(buffer, test_frame_size));
size_t len = udp->recv(boost::asio::buffer(buffer), echo_timeout);
if (len >= sizeof(x300_mtu_t))
len = uhd::ntohx<boost::uint32_t>(request->size);
- if (len >= test_mtu)
- min_send_mtu = test_mtu;
+ if (len >= test_frame_size)
+ min_send_frame_size = test_frame_size;
else
- max_send_mtu = test_mtu - 4;
+ max_send_frame_size = test_frame_size - 4;
+ }
+
+ if(min_send_frame_size < IP_PROTOCOL_MIN_MTU_SIZE-IP_PROTOCOL_UDP_PLUS_IP_HEADER) {
+ throw uhd::runtime_error("System send MTU size is less than the minimum required by the IP protocol.");
}
- UHD_MSG(status) << min_send_mtu << std::endl;
- mtu_result_t mtu;
- mtu.recv_mtu = min_recv_mtu;
- mtu.send_mtu = min_send_mtu;
- return mtu;
+ frame_size_t frame_size;
+ // There are cases when NICs accept oversized packets, in which case we'd falsely
+ // detect a larger-than-possible frame size. A safe and sensible value is the minimum
+ // of the recv and send frame sizes.
+ frame_size.recv_frame_size = std::min(min_recv_frame_size, min_send_frame_size);
+ frame_size.send_frame_size = std::min(min_recv_frame_size, min_send_frame_size);
+ UHD_MSG(status) << frame_size.send_frame_size << " bytes." << std::endl;
+ return frame_size;
}
/***********************************************************************
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 37f8cc468..1fb3676a0 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -58,21 +58,23 @@ static const double X300_BUS_CLOCK_RATE = 175e6; //Hz
static const size_t X300_TX_HW_BUFF_SIZE = 0x90000; //576KiB
static const size_t X300_TX_FC_RESPONSE_FREQ = 8; //per flow-control window
-static const size_t X300_RX_SW_BUFF_SIZE_ETH = 0x2000000; //32MiB For an ~8k MTU any size >32MiB is just wasted buffer space
-static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib
-static const double X300_RX_SW_BUFF_FULL_FACTOR = 0.90; //Buffer should ideally be 90% full.
-static const size_t X300_RX_FC_REQUEST_FREQ = 32; //per flow-control window
-
-static const size_t X300_PCIE_DATA_FRAME_SIZE = 8192; //bytes
-static const size_t X300_PCIE_DATA_NUM_FRAMES = 2048;
-static const size_t X300_PCIE_MSG_FRAME_SIZE = 256; //bytes
-static const size_t X300_PCIE_MSG_NUM_FRAMES = 32;
-
-static const size_t X300_ETH_DATA_FRAME_SIZE = 8000; //bytes
-static const size_t X300_ETH_DATA_NUM_FRAMES = 32;
-static const size_t X300_ETH_MSG_FRAME_SIZE = uhd::transport::udp_simple::mtu; //bytes
-static const size_t X300_ETH_MSG_NUM_FRAMES = 32;
-static const double X300_DEFAULT_SYSREF_RATE = 10e6;
+static const size_t X300_RX_SW_BUFF_SIZE_ETH = 0x2000000;//32MiB For an ~8k frame size any size >32MiB is just wasted buffer space
+static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib
+static const double X300_RX_SW_BUFF_FULL_FACTOR = 0.90; //Buffer should ideally be 90% full.
+static const size_t X300_RX_FC_REQUEST_FREQ = 32; //per flow-control window
+
+static const size_t X300_PCIE_DATA_FRAME_SIZE = 8192; //bytes
+static const size_t X300_PCIE_DATA_NUM_FRAMES = 2048;
+static const size_t X300_PCIE_MSG_FRAME_SIZE = 256; //bytes
+static const size_t X300_PCIE_MSG_NUM_FRAMES = 32;
+
+static const size_t X300_10GE_DATA_FRAME_MAX_SIZE = 8000; //bytes
+static const size_t X300_1GE_DATA_FRAME_MAX_SIZE = 1472; //bytes
+static const size_t X300_ETH_MSG_FRAME_SIZE = uhd::transport::udp_simple::mtu; //bytes
+
+static const size_t X300_ETH_MSG_NUM_FRAMES = 32;
+static const size_t X300_ETH_DATA_NUM_FRAMES = 32;
+static const double X300_DEFAULT_SYSREF_RATE = 10e6;
#define X300_RADIO_DEST_PREFIX_TX 0
#define X300_RADIO_DEST_PREFIX_CTRL 1
@@ -207,6 +209,9 @@ private:
int clock_control_regs__pps_out_enb;
int clock_control_regs__tcxo_enb;
int clock_control_regs__gpsdo_pwr;
+
+ //which FPGA image is loaded
+ std::string loaded_fpga_image;
};
std::vector<mboard_members_t> _mb;
@@ -243,13 +248,19 @@ private:
const uhd::device_addr_t& args,
boost::uint32_t& sid);
- struct mtu_result_t
+ struct frame_size_t
{
- size_t recv_mtu;
- size_t send_mtu;
+ size_t recv_frame_size;
+ size_t send_frame_size;
};
-
- mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &user_mtu);
+ frame_size_t max_frame_sizes;
+
+ /*!
+ * 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);
////////////////////////////////////////////////////////////////////
//