aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-07-25 08:08:43 -0700
committerMartin Braun <martin.braun@ettus.com>2019-08-02 11:03:11 -0700
commite2ce13e35d915c2d8b1300fd88745610c17638d1 (patch)
tree90c3656b118cf0698c359b20a93f59341b13fbeb /host
parent1210a633aeca082052621629a5643c661d7a7f34 (diff)
downloaduhd-e2ce13e35d915c2d8b1300fd88745610c17638d1.tar.gz
uhd-e2ce13e35d915c2d8b1300fd88745610c17638d1.tar.bz2
uhd-e2ce13e35d915c2d8b1300fd88745610c17638d1.zip
x300: Factor out mb-type specific code
This puts all functions that identify motherboards, distinguishes X310/X300/NI2974, checks MB revs etc. into its own compilation unit.
Diffstat (limited to 'host')
-rw-r--r--host/lib/usrp/x300/CMakeLists.txt2
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp166
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp6
-rw-r--r--host/lib/usrp/x300/x300_mboard_type.cpp166
-rw-r--r--host/lib/usrp/x300/x300_mboard_type.hpp45
5 files changed, 220 insertions, 165 deletions
diff --git a/host/lib/usrp/x300/CMakeLists.txt b/host/lib/usrp/x300/CMakeLists.txt
index 37fadf4d7..76a9e6b54 100644
--- a/host/lib/usrp/x300/CMakeLists.txt
+++ b/host/lib/usrp/x300/CMakeLists.txt
@@ -26,6 +26,8 @@ if(ENABLE_X300)
${CMAKE_CURRENT_SOURCE_DIR}/x300_image_loader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/x300_mb_eeprom_iface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/x300_mb_eeprom.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/x300_mboard_type.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/x300_mboard_type.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cdecode.c
)
endif(ENABLE_X300)
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 1113374f5..8ad1433d3 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -8,6 +8,7 @@
#include "x300_impl.hpp"
#include "x300_lvbitx.hpp"
#include "x300_mb_eeprom_iface.hpp"
+#include "x300_mboard_type.hpp"
#include "x310_lvbitx.hpp"
#include <uhd/transport/if_addrs.hpp>
#include <uhd/transport/nirio/niusrprio_session.h>
@@ -48,107 +49,10 @@ namespace asio = boost::asio;
/******************************************************************************
* Helpers
*****************************************************************************/
-static std::string get_fpga_option(wb_iface::sptr zpu_ctrl)
-{
- // Possible options:
- // 1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/
- // DRAM HA = {0:1G, 1:Aurora} w/ DRAM, XA = {0:10G, 1:Aurora} w/ DRAM
-
- std::string option;
- uint32_t sfp0_type = zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_SFP0_TYPE));
- uint32_t sfp1_type = zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_SFP1_TYPE));
-
- if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_1G_ETH) {
- option = "1G";
- } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_10G_ETH) {
- option = "HG";
- } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_10G_ETH) {
- option = "XG";
- } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_AURORA) {
- option = "HA";
- } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_AURORA) {
- option = "XA";
- } else {
- option = "HG"; // Default
- }
- return option;
-}
-
-
namespace {
constexpr unsigned int X300_UDP_RESERVED_FRAME_SIZE = 64;
-/*! Return the correct motherboard type for a given product ID
- *
- * Note: In previous versions, we had two different mappings for PCIe and
- * Ethernet in case the PIDs would conflict, but they never did and it was
- * thus consolidated into one.
- */
-x300_impl::x300_mboard_t map_pid_to_mb_type(const uint32_t pid)
-{
- switch (pid) {
- case X300_USRP_PCIE_SSID_ADC_33:
- case X300_USRP_PCIE_SSID_ADC_18:
- return x300_impl::USRP_X300_MB;
- case X310_USRP_PCIE_SSID_ADC_33:
- case X310_2940R_40MHz_PCIE_SSID_ADC_33:
- case X310_2940R_120MHz_PCIE_SSID_ADC_33:
- case X310_2942R_40MHz_PCIE_SSID_ADC_33:
- case X310_2942R_120MHz_PCIE_SSID_ADC_33:
- case X310_2943R_40MHz_PCIE_SSID_ADC_33:
- case X310_2943R_120MHz_PCIE_SSID_ADC_33:
- case X310_2944R_40MHz_PCIE_SSID_ADC_33:
- case X310_2950R_40MHz_PCIE_SSID_ADC_33:
- case X310_2950R_120MHz_PCIE_SSID_ADC_33:
- case X310_2952R_40MHz_PCIE_SSID_ADC_33:
- case X310_2952R_120MHz_PCIE_SSID_ADC_33:
- case X310_2953R_40MHz_PCIE_SSID_ADC_33:
- case X310_2953R_120MHz_PCIE_SSID_ADC_33:
- case X310_2954R_40MHz_PCIE_SSID_ADC_33:
- case X310_USRP_PCIE_SSID_ADC_18:
- case X310_2940R_40MHz_PCIE_SSID_ADC_18:
- case X310_2940R_120MHz_PCIE_SSID_ADC_18:
- case X310_2942R_40MHz_PCIE_SSID_ADC_18:
- case X310_2942R_120MHz_PCIE_SSID_ADC_18:
- case X310_2943R_40MHz_PCIE_SSID_ADC_18:
- case X310_2943R_120MHz_PCIE_SSID_ADC_18:
- case X310_2944R_40MHz_PCIE_SSID_ADC_18:
- case X310_2945R_PCIE_SSID_ADC_18:
- case X310_2950R_40MHz_PCIE_SSID_ADC_18:
- case X310_2950R_120MHz_PCIE_SSID_ADC_18:
- case X310_2952R_40MHz_PCIE_SSID_ADC_18:
- case X310_2952R_120MHz_PCIE_SSID_ADC_18:
- case X310_2953R_40MHz_PCIE_SSID_ADC_18:
- case X310_2953R_120MHz_PCIE_SSID_ADC_18:
- case X310_2954R_40MHz_PCIE_SSID_ADC_18:
- case X310_2955R_PCIE_SSID_ADC_18:
- return x300_impl::USRP_X310_MB;
- case X310_2974_PCIE_SSID_ADC_18:
- return x300_impl::USRP_X310_MB_NI_2974;
- default:
- return x300_impl::UNKNOWN;
- }
- UHD_THROW_INVALID_CODE_PATH();
-}
-
-/*! Map the motherboard type to a product name
- */
-std::string map_mb_type_to_product_name(
- const x300_impl::x300_mboard_t mb_type, const std::string& default_name = "")
-{
- switch (mb_type) {
- case x300_impl::USRP_X300_MB:
- return "X300";
- case x300_impl::USRP_X310_MB:
- return "X310";
- case x300_impl::USRP_X310_MB_NI_2974:
- return "NI-2974";
- default:
- return default_name;
- }
-}
-
} // namespace
static x300_impl::udp_simple_factory_t x300_get_udp_factory(const device_addr_t& args)
@@ -238,8 +142,8 @@ static device_addrs_t x300_find_with_addr(const device_addr_t& hint)
}
new_addr["name"] = mb_eeprom["name"];
new_addr["serial"] = mb_eeprom["serial"];
- const std::string product_name = map_mb_type_to_product_name(
- x300_impl::get_mb_type_from_eeprom(mb_eeprom));
+ const std::string product_name =
+ map_mb_type_to_product_name(get_mb_type_from_eeprom(mb_eeprom));
if (!product_name.empty()) {
new_addr["product"] = product_name;
}
@@ -1001,50 +905,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t& dev_addr)
////////////////////////////////////////////////////////////////////
// read hardware revision and compatibility number
////////////////////////////////////////////////////////////////////
- mb.hw_rev = 0;
- if (mb_eeprom.has_key("revision") and not mb_eeprom["revision"].empty()) {
- try {
- mb.hw_rev = boost::lexical_cast<size_t>(mb_eeprom["revision"]);
- } catch (...) {
- throw uhd::runtime_error(
- "Revision in EEPROM is invalid! Please reprogram your EEPROM.");
- }
- } else {
- throw uhd::runtime_error("No revision detected. MB EEPROM must be reprogrammed!");
- }
-
- size_t hw_rev_compat = 0;
- if (mb.hw_rev >= 7) { // Revision compat was added with revision 7
- if (mb_eeprom.has_key("revision_compat")
- and not mb_eeprom["revision_compat"].empty()) {
- try {
- hw_rev_compat = boost::lexical_cast<size_t>(mb_eeprom["revision_compat"]);
- } catch (...) {
- throw uhd::runtime_error("Revision compat in EEPROM is invalid! Please "
- "reprogram your EEPROM.");
- }
- } else {
- throw uhd::runtime_error(
- "No revision compat detected. MB EEPROM must be reprogrammed!");
- }
- } else {
- // For older HW just assume that revision_compat = revision
- hw_rev_compat = mb.hw_rev;
- }
-
- if (hw_rev_compat > X300_REVISION_COMPAT) {
- throw uhd::runtime_error(
- str(boost::format("Hardware is too new for this software. Please upgrade to "
- "a driver that supports hardware revision %d.")
- % mb.hw_rev));
- } else if (mb.hw_rev < X300_REVISION_MIN) { // Compare min against the revision (and
- // not compat) to give us more leeway for
- // partial support for a compat
- throw uhd::runtime_error(
- str(boost::format("Software is too new for this hardware. Please downgrade "
- "to a driver that supports hardware revision %d.")
- % mb.hw_rev));
- }
+ mb.hw_rev = get_and_check_hw_rev(mb_eeprom);
////////////////////////////////////////////////////////////////////
// create clock control objects
@@ -2106,7 +1967,7 @@ void x300_impl::check_fpga_compat(const fs_path& mb_path, const mboard_members_t
<< " git hash: " << git_hash_str);
}
-x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie(
+x300_mboard_t x300_impl::get_mb_type_from_pcie(
const std::string& resource, const std::string& rpc_port)
{
// Detect the PCIe product ID to distinguish between X300 and X310
@@ -2127,20 +1988,3 @@ x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie(
return UNKNOWN;
}
-x300_impl::x300_mboard_t x300_impl::get_mb_type_from_eeprom(
- const uhd::usrp::mboard_eeprom_t& mb_eeprom)
-{
- if (not mb_eeprom["product"].empty()) {
- uint16_t product_num = 0;
- try {
- product_num = boost::lexical_cast<uint16_t>(mb_eeprom["product"]);
- } catch (const boost::bad_lexical_cast&) {
- product_num = 0;
- }
-
- return map_pid_to_mb_type(product_num);
- }
-
- UHD_LOGGER_WARNING("X300") << "Unable to read product ID from EEPROM!";
- return UNKNOWN;
-}
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 8d50f9914..d8bd23592 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -13,6 +13,7 @@
#include "x300_defaults.hpp"
#include "x300_device_args.hpp"
#include "x300_fw_common.h"
+#include "x300_mboard_type.hpp"
#include "x300_radio_ctrl_impl.hpp"
#include "x300_regs.hpp"
#include <uhd/property_tree.hpp>
@@ -76,11 +77,8 @@ public:
static bool try_to_claim(uhd::wb_iface::sptr iface, long timeout = 2000);
static void release(uhd::wb_iface::sptr iface);
- enum x300_mboard_t { USRP_X300_MB, USRP_X310_MB, USRP_X310_MB_NI_2974, UNKNOWN };
- static x300_mboard_t get_mb_type_from_pcie(
+ static uhd::usrp::x300::x300_mboard_t get_mb_type_from_pcie(
const std::string& resource, const std::string& rpc_port);
- static x300_mboard_t get_mb_type_from_eeprom(
- const uhd::usrp::mboard_eeprom_t& mb_eeprom);
//! Read out the on-board EEPROM, convert to dict, and return
static uhd::usrp::mboard_eeprom_t get_mb_eeprom(uhd::i2c_iface::sptr i2c);
diff --git a/host/lib/usrp/x300/x300_mboard_type.cpp b/host/lib/usrp/x300/x300_mboard_type.cpp
new file mode 100644
index 000000000..fe6fcf59e
--- /dev/null
+++ b/host/lib/usrp/x300/x300_mboard_type.cpp
@@ -0,0 +1,166 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include "x300_mboard_type.hpp"
+#include "x300_fw_common.h"
+#include "x300_regs.hpp"
+#include <uhd/exception.hpp>
+#include <uhd/utils/log.hpp>
+#include <boost/lexical_cast.hpp>
+
+using namespace uhd::usrp::x300;
+
+x300_mboard_t uhd::usrp::x300::map_pid_to_mb_type(const uint32_t pid)
+{
+ switch (pid) {
+ case X300_USRP_PCIE_SSID_ADC_33:
+ case X300_USRP_PCIE_SSID_ADC_18:
+ return USRP_X300_MB;
+ case X310_USRP_PCIE_SSID_ADC_33:
+ case X310_2940R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2940R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2942R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2942R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2943R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2943R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2944R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2950R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2950R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2952R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2952R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2953R_40MHz_PCIE_SSID_ADC_33:
+ case X310_2953R_120MHz_PCIE_SSID_ADC_33:
+ case X310_2954R_40MHz_PCIE_SSID_ADC_33:
+ case X310_USRP_PCIE_SSID_ADC_18:
+ case X310_2940R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2940R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2942R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2942R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2943R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2943R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2944R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2945R_PCIE_SSID_ADC_18:
+ case X310_2950R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2950R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2952R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2952R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2953R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2953R_120MHz_PCIE_SSID_ADC_18:
+ case X310_2954R_40MHz_PCIE_SSID_ADC_18:
+ case X310_2955R_PCIE_SSID_ADC_18:
+ return USRP_X310_MB;
+ case X310_2974_PCIE_SSID_ADC_18:
+ return USRP_X310_MB_NI_2974;
+ default:
+ return UNKNOWN;
+ }
+ UHD_THROW_INVALID_CODE_PATH();
+}
+
+std::string uhd::usrp::x300::map_mb_type_to_product_name(
+ const x300_mboard_t mb_type, const std::string& default_name)
+{
+ switch (mb_type) {
+ case USRP_X300_MB:
+ return "X300";
+ case USRP_X310_MB:
+ return "X310";
+ case USRP_X310_MB_NI_2974:
+ return "NI-2974";
+ default:
+ return default_name;
+ }
+}
+
+size_t uhd::usrp::x300::get_and_check_hw_rev(const mboard_eeprom_t& mb_eeprom)
+{
+ size_t hw_rev;
+ if (mb_eeprom.has_key("revision") and not mb_eeprom["revision"].empty()) {
+ try {
+ hw_rev = boost::lexical_cast<size_t>(mb_eeprom["revision"]);
+ } catch (...) {
+ throw uhd::runtime_error(
+ "Revision in EEPROM is invalid! Please reprogram your EEPROM.");
+ }
+ } else {
+ throw uhd::runtime_error("No revision detected. MB EEPROM must be reprogrammed!");
+ }
+
+ size_t hw_rev_compat = 0;
+ if (hw_rev >= 7) { // Revision compat was added with revision 7
+ if (mb_eeprom.has_key("revision_compat")
+ and not mb_eeprom["revision_compat"].empty()) {
+ try {
+ hw_rev_compat = boost::lexical_cast<size_t>(mb_eeprom["revision_compat"]);
+ } catch (...) {
+ throw uhd::runtime_error("Revision compat in EEPROM is invalid! Please "
+ "reprogram your EEPROM.");
+ }
+ } else {
+ throw uhd::runtime_error(
+ "No revision compat detected. MB EEPROM must be reprogrammed!");
+ }
+ } else {
+ // For older HW just assume that revision_compat = revision
+ hw_rev_compat = hw_rev;
+ }
+
+ if (hw_rev_compat > X300_REVISION_COMPAT) {
+ throw uhd::runtime_error(
+ std::string("Hardware is too new for this software. Please upgrade to "
+ "a driver that supports hardware revision ")
+ + std::to_string(hw_rev));
+ } else if (hw_rev < X300_REVISION_MIN) { // Compare min against the revision (and
+ // not compat) to give us more leeway for
+ // partial support for a compat
+ throw uhd::runtime_error(
+ std::string("Software is too new for this hardware. Please downgrade "
+ "to a driver that supports hardware revision ")
+ + std::to_string(hw_rev));
+ }
+
+ return hw_rev;
+}
+
+x300_mboard_t uhd::usrp::x300::get_mb_type_from_eeprom(
+ const uhd::usrp::mboard_eeprom_t& mb_eeprom)
+{
+ if (not mb_eeprom["product"].empty()) {
+ uint16_t product_num = 0;
+ try {
+ product_num = boost::lexical_cast<uint16_t>(mb_eeprom["product"]);
+ } catch (const boost::bad_lexical_cast&) {
+ product_num = 0;
+ }
+
+ return map_pid_to_mb_type(product_num);
+ }
+
+ UHD_LOG_WARNING("X300", "Unable to read product ID from EEPROM!");
+ return UNKNOWN;
+}
+
+std::string uhd::usrp::x300::get_fpga_option(uhd::wb_iface::sptr zpu_ctrl)
+{
+ // Possible options:
+ // 1G = {0:1G, 1:1G} w/ DRAM, HG = {0:1G, 1:10G} w/ DRAM, XG = {0:10G, 1:10G} w/
+ // DRAM HA = {0:1G, 1:Aurora} w/ DRAM, XA = {0:10G, 1:Aurora} w/ DRAM
+ uint32_t sfp0_type = zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_SFP0_TYPE));
+ uint32_t sfp1_type = zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_SFP1_TYPE));
+
+ if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_1G_ETH) {
+ return "1G";
+ } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_10G_ETH) {
+ return "HG";
+ } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_10G_ETH) {
+ return "XG";
+ } else if (sfp0_type == RB_SFP_1G_ETH and sfp1_type == RB_SFP_AURORA) {
+ return "HA";
+ } else if (sfp0_type == RB_SFP_10G_ETH and sfp1_type == RB_SFP_AURORA) {
+ return "XA";
+ }
+ return "HG"; // Default
+}
diff --git a/host/lib/usrp/x300/x300_mboard_type.hpp b/host/lib/usrp/x300/x300_mboard_type.hpp
new file mode 100644
index 000000000..0a83aaf4d
--- /dev/null
+++ b/host/lib/usrp/x300/x300_mboard_type.hpp
@@ -0,0 +1,45 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#ifndef INCLUDED_X300_MBOARD_TYPE_HPP
+#define INCLUDED_X300_MBOARD_TYPE_HPP
+
+#include <uhd/types/wb_iface.hpp>
+#include <uhd/usrp/mboard_eeprom.hpp>
+#include <string>
+
+namespace uhd { namespace usrp { namespace x300 {
+
+enum x300_mboard_t { USRP_X300_MB, USRP_X310_MB, USRP_X310_MB_NI_2974, UNKNOWN };
+
+/*! Return the correct motherboard type for a given product ID
+ *
+ * Note: In previous versions, we had two different mappings for PCIe and
+ * Ethernet in case the PIDs would conflict, but they never did and it was
+ * thus consolidated into one.
+ */
+x300_mboard_t map_pid_to_mb_type(const uint32_t pid);
+
+/*! Map the motherboard type to a product name
+ */
+std::string map_mb_type_to_product_name(
+ const x300_mboard_t mb_type, const std::string& default_name = "");
+
+/*! Read HW revision (and HW compat revision) from mboard and run checks
+ *
+ * \throws uhd::runtime_error if the MB is not compatible with the SW
+ */
+size_t get_and_check_hw_rev(const uhd::usrp::mboard_eeprom_t& mb_eeprom);
+
+x300_mboard_t get_mb_type_from_eeprom(const uhd::usrp::mboard_eeprom_t& mb_eeprom);
+
+/*! Look up the FPGA type (XG, HG, etc.) in some ZPU registers
+ */
+std::string get_fpga_option(uhd::wb_iface::sptr zpu_ctrl);
+
+}}} // namespace uhd::usrp::x300
+
+#endif /* INCLUDED_X300_MBOARD_TYPE_HPP */