int get_rome_version(struct usb_device *udev, struct ath3k_version *version)
{
	struct ath3k_version fw_version;
	int ret;

	if (!version) {
		BT_ERR("NULL output parameters");
		return -EINVAL;
	}

	ret = ath3k_get_version(udev, &fw_version);
	if (ret < 0) {
		BT_ERR("Failed to get Rome Firmware version");
		return ret;
	}

	switch (fw_version.rom_version) {
	case ROME1_1_USB_CHIP_VERSION:
	case ROME2_1_USB_CHIP_VERSION:
	case ROME3_0_USB_CHIP_VERSION:
	case ROME3_2_USB_CHIP_VERSION:
		memcpy(version, &fw_version, sizeof(struct ath3k_version));
		ret = 0;
		break;
	default:
		BT_ERR("Unsupported ROME USB version");
		ret = -EINVAL;
		break;
	}

	return ret;
}
Example #2
0
int
ath3k_load_syscfg(libusb_device_handle *hdl, const char *fw_path)
{
	unsigned char fw_state;
	char filename[FILENAME_MAX];
	struct ath3k_firmware fw;
	struct ath3k_version fw_ver;
	int clk_value, ret;

	ret = ath3k_get_state(hdl, &fw_state);
	if (ret < 0) {
		ath3k_err("Can't get state to change to load configuration err");
		return (-EBUSY);
	}

	ret = ath3k_get_version(hdl, &fw_ver);
	if (ret < 0) {
		ath3k_err("Can't get version to change to load ram patch err");
		return (ret);
	}

	switch (fw_ver.ref_clock) {
	case ATH3K_XTAL_FREQ_26M:
		clk_value = 26;
		break;
	case ATH3K_XTAL_FREQ_40M:
		clk_value = 40;
		break;
	case ATH3K_XTAL_FREQ_19P2:
		clk_value = 19;
		break;
	default:
		clk_value = 0;
		break;
}

	snprintf(filename, FILENAME_MAX, "%s/ar3k/ramps_0x%08x_%d%s",
	    fw_path,
	    fw_ver.rom_version,
	    clk_value,
	    ".dfu");

	ath3k_info("%s: syscfg file = %s\n",
	    __func__,
	    filename);

	/* Read in the firmware */
	if (ath3k_fw_read(&fw, filename) <= 0) {
		ath3k_err("%s: ath3k_fw_read() failed\n",
		    __func__);
		return (-1);
	}

	ret = ath3k_load_fwfile(hdl, &fw);

	ath3k_fw_free(&fw);
	return (ret);
}
Example #3
0
int get_rome_version(struct usb_device *udev)
{
	struct ath3k_version fw_version;
	int ret = 0;

	ret = ath3k_get_version(udev, &fw_version);
	if (ret < 0) {
		BT_ERR("Failed to get Rome Firmware version");
		return ret;
	}

	switch (fw_version.rom_version) {
	case ROME1_1_USB_CHIP_VERSION:
	case ROME2_1_USB_CHIP_VERSION:
	case ROME3_0_USB_CHIP_VERSION:
		ret = fw_version.rom_version;
		break;
	default:
		ret = 0;
		break;
	}
	return ret;
}
Example #4
0
int
ath3k_load_patch(libusb_device_handle *hdl, const char *fw_path)
{
	int ret;
	unsigned char fw_state;
	struct ath3k_version fw_ver, pt_ver;
	char fwname[FILENAME_MAX];
	struct ath3k_firmware fw;
	uint32_t tmp;

	ret = ath3k_get_state(hdl, &fw_state);
	if (ret < 0) {
		ath3k_err("%s: Can't get state\n", __func__);
		return (ret);
	}

	if (fw_state & ATH3K_PATCH_UPDATE) {
		ath3k_info("%s: Patch already downloaded\n",
		    __func__);
		return (0);
	}

	ret = ath3k_get_version(hdl, &fw_ver);
	if (ret < 0) {
		ath3k_debug("%s: Can't get version\n", __func__);
		return (ret);
	}

	/* XXX path info? */
	snprintf(fwname, FILENAME_MAX, "%s/ar3k/AthrBT_0x%08x.dfu",
	    fw_path,
	    fw_ver.rom_version);

	/* Read in the firmware */
	if (ath3k_fw_read(&fw, fwname) <= 0) {
		ath3k_debug("%s: ath3k_fw_read() failed\n",
		    __func__);
		return (-1);
	}

	/*
	 * Extract the ROM/build version from the patch file.
	 */
	memcpy(&tmp, fw.buf + fw.len - 8, sizeof(tmp));
	pt_ver.rom_version = le32toh(tmp);
	memcpy(&tmp, fw.buf + fw.len - 4, sizeof(tmp));
	pt_ver.build_version = le32toh(tmp);

	ath3k_info("%s: file %s: rom_ver=%d, build_ver=%d\n",
	    __func__,
	    fwname,
	    (int) pt_ver.rom_version,
	    (int) pt_ver.build_version);

	/* Check the ROM/build version against the firmware */
	if ((pt_ver.rom_version != fw_ver.rom_version) ||
	    (pt_ver.build_version <= fw_ver.build_version)) {
		ath3k_debug("Patch file version mismatch!\n");
		ath3k_fw_free(&fw);
		return (-1);
	}

	/* Load in the firmware */
	ret = ath3k_load_fwfile(hdl, &fw);

	/* free it */
	ath3k_fw_free(&fw);

	return (ret);
}
Example #5
0
static int ath3k_load_syscfg(struct usb_device *udev)
{
	unsigned char fw_state;
	char filename[ATH3K_NAME_LEN] = {0};
	const struct firmware *firmware;
	struct ath3k_version fw_version;
	int clk_value, ret;

	ret = ath3k_get_state(udev, &fw_state);
	if (ret < 0) {
		BT_ERR("Can't get state to change to load configuration err");
		return -EBUSY;
	}

	if ((fw_state == ATH3K_SYSCFG_UPDATE) ||
		(fw_state == ATH3K_PATCH_SYSCFG_UPDATE)) {
		BT_INFO("%s: NVM already downloaded(fw_state: %d)", __func__,
			fw_state);
		return 0;
	} else
		BT_DBG("%s: Downloading NVM(fw_state: %d)", __func__, fw_state);

	ret = ath3k_get_version(udev, &fw_version);
	if (ret < 0) {
		BT_ERR("Can't get version to change to load ram patch err");
		return ret;
	}

	switch (fw_version.ref_clock) {

	case ATH3K_XTAL_FREQ_26M:
		clk_value = 26;
		break;
	case ATH3K_XTAL_FREQ_40M:
		clk_value = 40;
		break;
	case ATH3K_XTAL_FREQ_19P2:
		clk_value = 19;
		break;
	default:
		clk_value = 0;
		break;
	}

	if (fw_version.rom_version == ROME2_1_USB_CHIP_VERSION)
		snprintf(filename, ATH3K_NAME_LEN, ROME2_1_USB_NVM_FILE);
	else if (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION)
		snprintf(filename, ATH3K_NAME_LEN, ROME3_0_USB_NVM_FILE);
	else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION)
		snprintf(filename, ATH3K_NAME_LEN, ROME1_1_USB_NVM_FILE);
	else
		snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
			fw_version.rom_version, clk_value, ".dfu");

	ret = request_firmware(&firmware, filename, &udev->dev);
	if (ret < 0) {
		BT_ERR("Configuration file not found %s", filename);
		return ret;
	}

	if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) ||
		(fw_version.rom_version == ROME3_0_USB_CHIP_VERSION))
		ret = ath3k_load_fwfile(udev, firmware, ROME2_1_USB_NVM_HEADER);
	else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION)
		ret = ath3k_load_fwfile(udev, firmware, ROME1_1_USB_NVM_HEADER);
	else
		ret = ath3k_load_fwfile(udev, firmware, FW_HDR_SIZE);
	release_firmware(firmware);

	return ret;
}
Example #6
0
static int ath3k_load_patch(struct usb_device *udev)
{
	unsigned char fw_state;
	char filename[ATH3K_NAME_LEN] = {0};
	const struct firmware *firmware;
	struct ath3k_version fw_version, pt_version;
	struct rome2_1_version *rome2_1_version;
	struct rome1_1_version *rome1_1_version;
	int ret;

	ret = ath3k_get_state(udev, &fw_state);
	if (ret < 0) {
		BT_ERR("Can't get state to change to load ram patch err");
		return ret;
	}

	if ((fw_state == ATH3K_PATCH_UPDATE) ||
		(fw_state == ATH3K_PATCH_SYSCFG_UPDATE)) {
		BT_INFO("%s: Patch already downloaded(fw_state: %d)", __func__,
			fw_state);
		return 0;
	} else
		BT_DBG("%s: Downloading RamPatch(fw_state: %d)", __func__,
			fw_state);

	ret = ath3k_get_version(udev, &fw_version);
	if (ret < 0) {
		BT_ERR("Can't get version to change to load ram patch err");
		return ret;
	}
	if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) {
		BT_DBG("Chip Detected as ROME1.1");
		snprintf(filename, ATH3K_NAME_LEN, ROME1_1_USB_RAMPATCH_FILE);
	} else if (fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) {
		BT_DBG("Chip Detected as ROME2.1");
		snprintf(filename, ATH3K_NAME_LEN, ROME2_1_USB_RAMPATCH_FILE);
	} else if (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION) {
		BT_DBG("Chip Detected as ROME3.0");
		snprintf(filename, ATH3K_NAME_LEN, ROME3_0_USB_RAMPATCH_FILE);
	} else {
		BT_DBG("Chip Detected as Ath3k");
		snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
		fw_version.rom_version);
	}
	ret = request_firmware(&firmware, filename, &udev->dev);
	if (ret < 0) {
		BT_ERR("Patch file not found %s", filename);
		return ret;
	}

	if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) ||
		(fw_version.rom_version == ROME3_0_USB_CHIP_VERSION)) {
		rome2_1_version = (struct rome2_1_version *) firmware->data;
		pt_version.rom_version = rome2_1_version->build_ver;
		pt_version.build_version = rome2_1_version->patch_ver;
		BT_DBG("pt_ver.rome_ver : 0x%x", pt_version.rom_version);
		BT_DBG("pt_ver.build_ver: 0x%x", pt_version.build_version);
		BT_DBG("fw_ver.rom_ver: 0x%x", fw_version.rom_version);
		BT_DBG("fw_ver.build_ver: 0x%x", fw_version.build_version);
	} else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) {
		rome1_1_version = (struct rome1_1_version *) firmware->data;
		pt_version.build_version = rome1_1_version->build_ver;
		pt_version.rom_version = rome1_1_version->patch_ver;
		BT_DBG("pt_ver.rom1.1_ver : 0x%x", pt_version.rom_version);
		BT_DBG("pt_ver.build1.1_ver: 0x%x", pt_version.build_version);
		BT_DBG("fw_ver.rom1.1_ver: 0x%x", fw_version.rom_version);
		BT_DBG("fw_ver.build1.1_ver: 0x%x", fw_version.build_version);
	} else {
		pt_version.rom_version = *(int *)(firmware->data +
						firmware->size - 8);
		pt_version.build_version = *(int *)
		(firmware->data + firmware->size - 4);
	}
	if ((pt_version.rom_version != fw_version.rom_version) ||
		(pt_version.build_version <= fw_version.build_version)) {
		BT_ERR("Patch file version did not match with firmware");
		release_firmware(firmware);
		return -EINVAL;
	}

	if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) ||
		(fw_version.rom_version == ROME3_0_USB_CHIP_VERSION))
		ret = ath3k_load_fwfile(udev, firmware,
						ROME2_1_USB_RAMPATCH_HEADER);
	else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION)
		ret = ath3k_load_fwfile(udev, firmware,
						 ROME1_1_USB_RAMPATCH_HEADER);
	else
		ret = ath3k_load_fwfile(udev, firmware, FW_HDR_SIZE);

	release_firmware(firmware);

	return ret;
}