int fpga_check_version(struct bladerf *dev) { int status = version_check_fpga(dev); #if LOGGING_ENABLED const unsigned int fw_maj = dev->fw_version.major; const unsigned int fw_min = dev->fw_version.minor; const unsigned int fw_pat = dev->fw_version.patch; const unsigned int fpga_maj = dev->fpga_version.major; const unsigned int fpga_min = dev->fpga_version.minor; const unsigned int fpga_pat = dev->fpga_version.patch; unsigned int req_maj, req_min, req_pat; struct bladerf_version req; if (status == BLADERF_ERR_UPDATE_FPGA) { version_required_fpga(dev, &req); req_maj = req.major; req_min = req.minor; req_pat = req.patch; log_warning("FPGA v%u.%u.%u was detected. Firmware v%u.%u.%u " "requires FPGA v%u.%u.%u or later. Please load a " "different FPGA version before continuing.\n\n", fpga_maj, fpga_min, fpga_pat, fw_maj, fw_min, fw_pat, req_maj, req_min, req_pat); } else if (status == BLADERF_ERR_UPDATE_FW) { version_required_fw(dev, &req, true); req_maj = req.major; req_min = req.minor; req_pat = req.patch; log_warning("FPGA v%u.%u.%u was detected, which requires firmware " "v%u.%u.%u or later. The device firmware is currently " "v%u.%u.%u. Please upgrade the device firmware before " "continuing.\n\n", fpga_maj, fpga_min, fpga_pat, req_maj, req_min, req_pat, fw_maj, fw_min, fw_pat); } #endif return status; }
int bladerf_open_with_devinfo(struct bladerf **opened_device, struct bladerf_devinfo *devinfo) { struct bladerf *dev; int status; *opened_device = NULL; dev = (struct bladerf *)calloc(1, sizeof(struct bladerf)); if (dev == NULL) { return BLADERF_ERR_MEM; } MUTEX_INIT(&dev->ctrl_lock); MUTEX_INIT(&dev->sync_lock[BLADERF_MODULE_RX]); MUTEX_INIT(&dev->sync_lock[BLADERF_MODULE_TX]); dev->fpga_version.describe = calloc(1, BLADERF_VERSION_STR_MAX + 1); if (dev->fpga_version.describe == NULL) { free(dev); return BLADERF_ERR_MEM; } dev->fw_version.describe = calloc(1, BLADERF_VERSION_STR_MAX + 1); if (dev->fw_version.describe == NULL) { free((void*)dev->fpga_version.describe); free(dev); return BLADERF_ERR_MEM; } status = backend_open(dev, devinfo); if (status != 0) { free((void*)dev->fw_version.describe); free((void*)dev->fpga_version.describe); free(dev); return status; } status = dev->fn->get_device_speed(dev, &dev->usb_speed); if (status < 0) { log_debug("Failed to get device speed: %s\n", bladerf_strerror(status)); goto error; } if (dev->usb_speed != BLADERF_DEVICE_SPEED_HIGH && dev->usb_speed != BLADERF_DEVICE_SPEED_SUPER) { log_debug("Unsupported device speed: %d\n", dev->usb_speed); goto error; } /* Verify that we have a sufficent firmware version before continuing. */ status = version_check_fw(dev); if (status != 0) { #ifdef LOGGING_ENABLED if (status == BLADERF_ERR_UPDATE_FW) { struct bladerf_version req; const unsigned int dev_maj = dev->fw_version.major; const unsigned int dev_min = dev->fw_version.minor; const unsigned int dev_pat = dev->fw_version.patch; unsigned int req_maj, req_min, req_pat; version_required_fw(dev, &req, false); req_maj = req.major; req_min = req.minor; req_pat = req.patch; log_warning("Firmware v%u.%u.%u was detected. libbladeRF v%s " "requires firmware v%u.%u.%u or later. An upgrade via " "the bootloader is required.\n\n", dev_maj, dev_min, dev_pat, LIBBLADERF_VERSION, req_maj, req_min, req_pat); } #endif goto error; } /* VCTCXO trim and FPGA size are non-fatal indicators that we've * trashed the calibration region of flash. If these were made fatal, * we wouldn't be able to open the device to restore them. */ status = get_and_cache_vctcxo_trim(dev); if (status < 0) { log_warning("Failed to get VCTCXO trim value: %s\n", bladerf_strerror(status)); } status = get_and_cache_fpga_size(dev); if (status < 0) { log_warning("Failed to get FPGA size %s\n", bladerf_strerror(status)); } status = FPGA_IS_CONFIGURED(dev); if (status > 0) { /* If the FPGA version check fails, just warn, but don't error out. * * If an error code caused this function to bail out, it would prevent a * user from being able to unload and reflash a bitstream being * "autoloaded" from SPI flash. */ fpga_check_version(dev); status = init_device(dev); if (status != 0) { goto error; } } dev->rx_filter = -1; dev->tx_filter = -1; /* Load any configuration files or FPGA images that a user has stored * for this device in their bladerf config directory */ status = config_load_all(dev); error: if (status < 0) { bladerf_close(dev); } else { *opened_device = dev; } return status; }