int qca_uart_setup()

in btqca.c [577:698]


int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
		   enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
		   const char *firmware_name)
{
	struct qca_fw_config config;
	int err;
	u8 rom_ver = 0;
	u32 soc_ver;

	bt_dev_dbg(hdev, "QCA setup on UART");

	soc_ver = get_soc_ver(ver.soc_id, ver.rom_ver);

	bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);

	config.user_baud_rate = baudrate;

	/* Firmware files to download are based on ROM version.
	 * ROM version is derived from last two bytes of soc_ver.
	 */
	rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f);

	if (soc_type == QCA_WCN6750)
		qca_send_patch_config_cmd(hdev);

	/* Download rampatch file */
	config.type = TLV_TYPE_PATCH;
	if (qca_is_wcn399x(soc_type)) {
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/crbtfw%02x.tlv", rom_ver);
	} else if (soc_type == QCA_QCA6390) {
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/htbtfw%02x.tlv", rom_ver);
	} else if (soc_type == QCA_WCN6750) {
		/* Choose mbn file by default.If mbn file is not found
		 * then choose tlv file
		 */
		config.type = ELF_TYPE_PATCH;
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/msbtfw%02x.mbn", rom_ver);
	} else {
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/rampatch_%08x.bin", soc_ver);
	}

	err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
	if (err < 0) {
		bt_dev_err(hdev, "QCA Failed to download patch (%d)", err);
		return err;
	}

	/* Give the controller some time to get ready to receive the NVM */
	msleep(10);

	/* Download NVM configuration */
	config.type = TLV_TYPE_NVM;
	if (firmware_name)
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/%s", firmware_name);
	else if (qca_is_wcn399x(soc_type)) {
		if (ver.soc_id == QCA_WCN3991_SOC_ID) {
			snprintf(config.fwname, sizeof(config.fwname),
				 "qca/crnv%02xu.bin", rom_ver);
		} else {
			snprintf(config.fwname, sizeof(config.fwname),
				 "qca/crnv%02x.bin", rom_ver);
		}
	}
	else if (soc_type == QCA_QCA6390)
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/htnv%02x.bin", rom_ver);
	else if (soc_type == QCA_WCN6750)
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/msnv%02x.bin", rom_ver);
	else
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/nvm_%08x.bin", soc_ver);

	err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
	if (err < 0) {
		bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err);
		return err;
	}

	if (soc_type >= QCA_WCN3991) {
		err = qca_disable_soc_logging(hdev);
		if (err < 0)
			return err;
	}

	/* WCN399x and WCN6750 supports the Microsoft vendor extension with 0xFD70 as the
	 * VsMsftOpCode.
	 */
	switch (soc_type) {
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
	case QCA_WCN6750:
		hci_set_msft_opcode(hdev, 0xFD70);
		break;
	default:
		break;
	}

	/* Perform HCI reset */
	err = qca_send_reset(hdev);
	if (err < 0) {
		bt_dev_err(hdev, "QCA Failed to run HCI_RESET (%d)", err);
		return err;
	}

	if (soc_type == QCA_WCN3991 || soc_type == QCA_WCN6750) {
		/* get fw build info */
		err = qca_read_fw_build_info(hdev);
		if (err < 0)
			return err;
	}

	bt_dev_info(hdev, "QCA setup on UART is completed");

	return 0;
}