brintos

brintos / linux-shallow public Read only

0
0
Text · 22.8 KiB · dfbbac9 Raw
958 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 *  Bluetooth supports for Qualcomm Atheros chips4 *5 *  Copyright (c) 2015 The Linux Foundation. All rights reserved.6 */7#include <linux/module.h>8#include <linux/firmware.h>9#include <linux/vmalloc.h>10 11#include <net/bluetooth/bluetooth.h>12#include <net/bluetooth/hci_core.h>13 14#include "btqca.h"15 16int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,17			 enum qca_btsoc_type soc_type)18{19	struct sk_buff *skb;20	struct edl_event_hdr *edl;21	char cmd;22	int err = 0;23	u8 event_type = HCI_EV_VENDOR;24	u8 rlen = sizeof(*edl) + sizeof(*ver);25	u8 rtype = EDL_APP_VER_RES_EVT;26 27	bt_dev_dbg(hdev, "QCA Version Request");28 29	/* Unlike other SoC's sending version command response as payload to30	 * VSE event. WCN3991 sends version command response as a payload to31	 * command complete event.32	 */33	if (soc_type >= QCA_WCN3991) {34		event_type = 0;35		rlen += 1;36		rtype = EDL_PATCH_VER_REQ_CMD;37	}38 39	cmd = EDL_PATCH_VER_REQ_CMD;40	skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN,41				&cmd, event_type, HCI_INIT_TIMEOUT);42	if (IS_ERR(skb)) {43		err = PTR_ERR(skb);44		bt_dev_err(hdev, "Reading QCA version information failed (%d)",45			   err);46		return err;47	}48 49	if (skb->len != rlen) {50		bt_dev_err(hdev, "QCA Version size mismatch len %d", skb->len);51		err = -EILSEQ;52		goto out;53	}54 55	edl = (struct edl_event_hdr *)(skb->data);56 57	if (edl->cresp != EDL_CMD_REQ_RES_EVT ||58	    edl->rtype != rtype) {59		bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,60			   edl->rtype);61		err = -EIO;62		goto out;63	}64 65	if (soc_type >= QCA_WCN3991)66		memcpy(ver, edl->data + 1, sizeof(*ver));67	else68		memcpy(ver, &edl->data, sizeof(*ver));69 70	bt_dev_info(hdev, "QCA Product ID   :0x%08x",71		    le32_to_cpu(ver->product_id));72	bt_dev_info(hdev, "QCA SOC Version  :0x%08x",73		    le32_to_cpu(ver->soc_id));74	bt_dev_info(hdev, "QCA ROM Version  :0x%08x",75		    le16_to_cpu(ver->rom_ver));76	bt_dev_info(hdev, "QCA Patch Version:0x%08x",77		    le16_to_cpu(ver->patch_ver));78 79	if (ver->soc_id == 0 || ver->rom_ver == 0)80		err = -EILSEQ;81 82out:83	kfree_skb(skb);84	if (err)85		bt_dev_err(hdev, "QCA Failed to get version (%d)", err);86 87	return err;88}89EXPORT_SYMBOL_GPL(qca_read_soc_version);90 91static int qca_read_fw_build_info(struct hci_dev *hdev)92{93	struct sk_buff *skb;94	struct edl_event_hdr *edl;95	char *build_label;96	char cmd;97	int build_lbl_len, err = 0;98 99	bt_dev_dbg(hdev, "QCA read fw build info");100 101	cmd = EDL_GET_BUILD_INFO_CMD;102	skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN,103				&cmd, 0, HCI_INIT_TIMEOUT);104	if (IS_ERR(skb)) {105		err = PTR_ERR(skb);106		bt_dev_err(hdev, "Reading QCA fw build info failed (%d)",107			   err);108		return err;109	}110 111	if (skb->len < sizeof(*edl)) {112		err = -EILSEQ;113		goto out;114	}115 116	edl = (struct edl_event_hdr *)(skb->data);117 118	if (edl->cresp != EDL_CMD_REQ_RES_EVT ||119	    edl->rtype != EDL_GET_BUILD_INFO_CMD) {120		bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,121			   edl->rtype);122		err = -EIO;123		goto out;124	}125 126	if (skb->len < sizeof(*edl) + 1) {127		err = -EILSEQ;128		goto out;129	}130 131	build_lbl_len = edl->data[0];132 133	if (skb->len < sizeof(*edl) + 1 + build_lbl_len) {134		err = -EILSEQ;135		goto out;136	}137 138	build_label = kstrndup(&edl->data[1], build_lbl_len, GFP_KERNEL);139	if (!build_label) {140		err = -ENOMEM;141		goto out;142	}143 144	hci_set_fw_info(hdev, "%s", build_label);145 146	kfree(build_label);147out:148	kfree_skb(skb);149	return err;150}151 152static int qca_send_patch_config_cmd(struct hci_dev *hdev)153{154	const u8 cmd[] = { EDL_PATCH_CONFIG_CMD, 0x01, 0, 0, 0 };155	struct sk_buff *skb;156	struct edl_event_hdr *edl;157	int err;158 159	bt_dev_dbg(hdev, "QCA Patch config");160 161	skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, sizeof(cmd),162				cmd, 0, HCI_INIT_TIMEOUT);163	if (IS_ERR(skb)) {164		err = PTR_ERR(skb);165		bt_dev_err(hdev, "Sending QCA Patch config failed (%d)", err);166		return err;167	}168 169	if (skb->len != 2) {170		bt_dev_err(hdev, "QCA Patch config cmd size mismatch len %d", skb->len);171		err = -EILSEQ;172		goto out;173	}174 175	edl = (struct edl_event_hdr *)(skb->data);176 177	if (edl->cresp != EDL_PATCH_CONFIG_RES_EVT || edl->rtype != EDL_PATCH_CONFIG_CMD) {178		bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,179			   edl->rtype);180		err = -EIO;181		goto out;182	}183 184	err = 0;185 186out:187	kfree_skb(skb);188	return err;189}190 191static int qca_send_reset(struct hci_dev *hdev)192{193	struct sk_buff *skb;194	int err;195 196	bt_dev_dbg(hdev, "QCA HCI_RESET");197 198	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);199	if (IS_ERR(skb)) {200		err = PTR_ERR(skb);201		bt_dev_err(hdev, "QCA Reset failed (%d)", err);202		return err;203	}204 205	kfree_skb(skb);206 207	return 0;208}209 210static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid)211{212	u8 cmd;213	struct sk_buff *skb;214	struct edl_event_hdr *edl;215	int err = 0;216 217	cmd = EDL_GET_BID_REQ_CMD;218	skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN,219				&cmd, 0, HCI_INIT_TIMEOUT);220	if (IS_ERR(skb)) {221		err = PTR_ERR(skb);222		bt_dev_err(hdev, "Reading QCA board ID failed (%d)", err);223		return err;224	}225 226	edl = skb_pull_data(skb, sizeof(*edl));227	if (!edl) {228		bt_dev_err(hdev, "QCA read board ID with no header");229		err = -EILSEQ;230		goto out;231	}232 233	if (edl->cresp != EDL_CMD_REQ_RES_EVT ||234	    edl->rtype != EDL_GET_BID_REQ_CMD) {235		bt_dev_err(hdev, "QCA Wrong packet: %d %d", edl->cresp, edl->rtype);236		err = -EIO;237		goto out;238	}239 240	if (skb->len < 3) {241		err = -EILSEQ;242		goto out;243	}244 245	*bid = (edl->data[1] << 8) + edl->data[2];246	bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid);247 248out:249	kfree_skb(skb);250	return err;251}252 253int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)254{255	struct sk_buff *skb;256	int err;257 258	bt_dev_dbg(hdev, "QCA pre shutdown cmd");259 260	skb = __hci_cmd_sync_ev(hdev, QCA_PRE_SHUTDOWN_CMD, 0,261				NULL, HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);262 263	if (IS_ERR(skb)) {264		err = PTR_ERR(skb);265		bt_dev_err(hdev, "QCA preshutdown_cmd failed (%d)", err);266		return err;267	}268 269	kfree_skb(skb);270 271	return 0;272}273EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);274 275static int qca_tlv_check_data(struct hci_dev *hdev,276			       struct qca_fw_config *config,277			       u8 *fw_data, size_t fw_size,278			       enum qca_btsoc_type soc_type)279{280	const u8 *data;281	u32 type_len;282	u16 tag_id, tag_len;283	int idx, length;284	struct tlv_type_hdr *tlv;285	struct tlv_type_patch *tlv_patch;286	struct tlv_type_nvm *tlv_nvm;287	uint8_t nvm_baud_rate = config->user_baud_rate;288	u8 type;289 290	config->dnld_mode = QCA_SKIP_EVT_NONE;291	config->dnld_type = QCA_SKIP_EVT_NONE;292 293	switch (config->type) {294	case ELF_TYPE_PATCH:295		if (fw_size < 7)296			return -EINVAL;297 298		config->dnld_mode = QCA_SKIP_EVT_VSE_CC;299		config->dnld_type = QCA_SKIP_EVT_VSE_CC;300 301		bt_dev_dbg(hdev, "File Class        : 0x%x", fw_data[4]);302		bt_dev_dbg(hdev, "Data Encoding     : 0x%x", fw_data[5]);303		bt_dev_dbg(hdev, "File version      : 0x%x", fw_data[6]);304		break;305	case TLV_TYPE_PATCH:306		if (fw_size < sizeof(struct tlv_type_hdr) + sizeof(struct tlv_type_patch))307			return -EINVAL;308 309		tlv = (struct tlv_type_hdr *)fw_data;310		type_len = le32_to_cpu(tlv->type_len);311		tlv_patch = (struct tlv_type_patch *)tlv->data;312 313		/* For Rome version 1.1 to 3.1, all segment commands314		 * are acked by a vendor specific event (VSE).315		 * For Rome >= 3.2, the download mode field indicates316		 * if VSE is skipped by the controller.317		 * In case VSE is skipped, only the last segment is acked.318		 */319		config->dnld_mode = tlv_patch->download_mode;320		config->dnld_type = config->dnld_mode;321 322		BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);323		BT_DBG("Total Length           : %d bytes",324		       le32_to_cpu(tlv_patch->total_size));325		BT_DBG("Patch Data Length      : %d bytes",326		       le32_to_cpu(tlv_patch->data_length));327		BT_DBG("Signing Format Version : 0x%x",328		       tlv_patch->format_version);329		BT_DBG("Signature Algorithm    : 0x%x",330		       tlv_patch->signature);331		BT_DBG("Download mode          : 0x%x",332		       tlv_patch->download_mode);333		BT_DBG("Reserved               : 0x%x",334		       tlv_patch->reserved1);335		BT_DBG("Product ID             : 0x%04x",336		       le16_to_cpu(tlv_patch->product_id));337		BT_DBG("Rom Build Version      : 0x%04x",338		       le16_to_cpu(tlv_patch->rom_build));339		BT_DBG("Patch Version          : 0x%04x",340		       le16_to_cpu(tlv_patch->patch_version));341		BT_DBG("Reserved               : 0x%x",342		       le16_to_cpu(tlv_patch->reserved2));343		BT_DBG("Patch Entry Address    : 0x%x",344		       le32_to_cpu(tlv_patch->entry));345		break;346 347	case TLV_TYPE_NVM:348		if (fw_size < sizeof(struct tlv_type_hdr))349			return -EINVAL;350 351		tlv = (struct tlv_type_hdr *)fw_data;352 353		type_len = le32_to_cpu(tlv->type_len);354		length = type_len >> 8;355		type = type_len & 0xff;356 357		/* Some NVM files have more than one set of tags, only parse358		 * the first set when it has type 2 for now. When there is359		 * more than one set there is an enclosing header of type 4.360		 */361		if (type == 4) {362			if (fw_size < 2 * sizeof(struct tlv_type_hdr))363				return -EINVAL;364 365			tlv++;366 367			type_len = le32_to_cpu(tlv->type_len);368			length = type_len >> 8;369			type = type_len & 0xff;370		}371 372		BT_DBG("TLV Type\t\t : 0x%x", type);373		BT_DBG("Length\t\t : %d bytes", length);374 375		if (type != 2)376			break;377 378		if (fw_size < length + (tlv->data - fw_data))379			return -EINVAL;380 381		idx = 0;382		data = tlv->data;383		while (idx < length - sizeof(struct tlv_type_nvm)) {384			tlv_nvm = (struct tlv_type_nvm *)(data + idx);385 386			tag_id = le16_to_cpu(tlv_nvm->tag_id);387			tag_len = le16_to_cpu(tlv_nvm->tag_len);388 389			if (length < idx + sizeof(struct tlv_type_nvm) + tag_len)390				return -EINVAL;391 392			/* Update NVM tags as needed */393			switch (tag_id) {394			case EDL_TAG_ID_BD_ADDR:395				if (tag_len != sizeof(bdaddr_t))396					return -EINVAL;397 398				memcpy(&config->bdaddr, tlv_nvm->data, sizeof(bdaddr_t));399 400				break;401 402			case EDL_TAG_ID_HCI:403				if (tag_len < 3)404					return -EINVAL;405 406				/* HCI transport layer parameters407				 * enabling software inband sleep408				 * onto controller side.409				 */410				tlv_nvm->data[0] |= 0x80;411 412				/* UART Baud Rate */413				if (soc_type >= QCA_WCN3991)414					tlv_nvm->data[1] = nvm_baud_rate;415				else416					tlv_nvm->data[2] = nvm_baud_rate;417 418				break;419 420			case EDL_TAG_ID_DEEP_SLEEP:421				if (tag_len < 1)422					return -EINVAL;423 424				/* Sleep enable mask425				 * enabling deep sleep feature on controller.426				 */427				tlv_nvm->data[0] |= 0x01;428 429				break;430			}431 432			idx += sizeof(struct tlv_type_nvm) + tag_len;433		}434		break;435 436	default:437		BT_ERR("Unknown TLV type %d", config->type);438		return -EINVAL;439	}440 441	return 0;442}443 444static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,445				const u8 *data, enum qca_tlv_dnld_mode mode,446				enum qca_btsoc_type soc_type)447{448	struct sk_buff *skb;449	struct edl_event_hdr *edl;450	struct tlv_seg_resp *tlv_resp;451	u8 cmd[MAX_SIZE_PER_TLV_SEGMENT + 2];452	int err = 0;453	u8 event_type = HCI_EV_VENDOR;454	u8 rlen = (sizeof(*edl) + sizeof(*tlv_resp));455	u8 rtype = EDL_TVL_DNLD_RES_EVT;456 457	cmd[0] = EDL_PATCH_TLV_REQ_CMD;458	cmd[1] = seg_size;459	memcpy(cmd + 2, data, seg_size);460 461	if (mode == QCA_SKIP_EVT_VSE_CC || mode == QCA_SKIP_EVT_VSE)462		return __hci_cmd_send(hdev, EDL_PATCH_CMD_OPCODE, seg_size + 2,463				      cmd);464 465	/* Unlike other SoC's sending version command response as payload to466	 * VSE event. WCN3991 sends version command response as a payload to467	 * command complete event.468	 */469	if (soc_type >= QCA_WCN3991) {470		event_type = 0;471		rlen = sizeof(*edl);472		rtype = EDL_PATCH_TLV_REQ_CMD;473	}474 475	skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, seg_size + 2, cmd,476				event_type, HCI_INIT_TIMEOUT);477	if (IS_ERR(skb)) {478		err = PTR_ERR(skb);479		bt_dev_err(hdev, "QCA Failed to send TLV segment (%d)", err);480		return err;481	}482 483	if (skb->len != rlen) {484		bt_dev_err(hdev, "QCA TLV response size mismatch");485		err = -EILSEQ;486		goto out;487	}488 489	edl = (struct edl_event_hdr *)(skb->data);490 491	if (edl->cresp != EDL_CMD_REQ_RES_EVT || edl->rtype != rtype) {492		bt_dev_err(hdev, "QCA TLV with error stat 0x%x rtype 0x%x",493			   edl->cresp, edl->rtype);494		err = -EIO;495	}496 497	if (soc_type >= QCA_WCN3991)498		goto out;499 500	tlv_resp = (struct tlv_seg_resp *)(edl->data);501	if (tlv_resp->result) {502		bt_dev_err(hdev, "QCA TLV with error stat 0x%x rtype 0x%x (0x%x)",503			   edl->cresp, edl->rtype, tlv_resp->result);504	}505 506out:507	kfree_skb(skb);508 509	return err;510}511 512static int qca_inject_cmd_complete_event(struct hci_dev *hdev)513{514	struct hci_event_hdr *hdr;515	struct hci_ev_cmd_complete *evt;516	struct sk_buff *skb;517 518	skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);519	if (!skb)520		return -ENOMEM;521 522	hdr = skb_put(skb, sizeof(*hdr));523	hdr->evt = HCI_EV_CMD_COMPLETE;524	hdr->plen = sizeof(*evt) + 1;525 526	evt = skb_put(skb, sizeof(*evt));527	evt->ncmd = 1;528	evt->opcode = cpu_to_le16(QCA_HCI_CC_OPCODE);529 530	skb_put_u8(skb, QCA_HCI_CC_SUCCESS);531 532	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;533 534	return hci_recv_frame(hdev, skb);535}536 537static int qca_download_firmware(struct hci_dev *hdev,538				 struct qca_fw_config *config,539				 enum qca_btsoc_type soc_type,540				 u8 rom_ver)541{542	const struct firmware *fw;543	u8 *data;544	const u8 *segment;545	int ret, size, remain, i = 0;546 547	bt_dev_info(hdev, "QCA Downloading %s", config->fwname);548 549	ret = request_firmware(&fw, config->fwname, &hdev->dev);550	if (ret) {551		/* For WCN6750, if mbn file is not present then check for552		 * tlv file.553		 */554		if (soc_type == QCA_WCN6750 && config->type == ELF_TYPE_PATCH) {555			bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)",556				   config->fwname, ret);557			config->type = TLV_TYPE_PATCH;558			snprintf(config->fwname, sizeof(config->fwname),559				 "qca/msbtfw%02x.tlv", rom_ver);560			bt_dev_info(hdev, "QCA Downloading %s", config->fwname);561			ret = request_firmware(&fw, config->fwname, &hdev->dev);562			if (ret) {563				bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",564					   config->fwname, ret);565				return ret;566			}567		} else {568			bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",569				   config->fwname, ret);570			return ret;571		}572	}573 574	size = fw->size;575	data = vmalloc(fw->size);576	if (!data) {577		bt_dev_err(hdev, "QCA Failed to allocate memory for file: %s",578			   config->fwname);579		release_firmware(fw);580		return -ENOMEM;581	}582 583	memcpy(data, fw->data, size);584	release_firmware(fw);585 586	ret = qca_tlv_check_data(hdev, config, data, size, soc_type);587	if (ret)588		goto out;589 590	segment = data;591	remain = size;592	while (remain > 0) {593		int segsize = min(MAX_SIZE_PER_TLV_SEGMENT, remain);594 595		bt_dev_dbg(hdev, "Send segment %d, size %d", i++, segsize);596 597		remain -= segsize;598		/* The last segment is always acked regardless download mode */599		if (!remain || segsize < MAX_SIZE_PER_TLV_SEGMENT)600			config->dnld_mode = QCA_SKIP_EVT_NONE;601 602		ret = qca_tlv_send_segment(hdev, segsize, segment,603					   config->dnld_mode, soc_type);604		if (ret)605			goto out;606 607		segment += segsize;608	}609 610	/* Latest qualcomm chipsets are not sending a command complete event611	 * for every fw packet sent. They only respond with a vendor specific612	 * event for the last packet. This optimization in the chip will613	 * decrease the BT in initialization time. Here we will inject a command614	 * complete event to avoid a command timeout error message.615	 */616	if (config->dnld_type == QCA_SKIP_EVT_VSE_CC ||617	    config->dnld_type == QCA_SKIP_EVT_VSE)618		ret = qca_inject_cmd_complete_event(hdev);619 620out:621	vfree(data);622 623	return ret;624}625 626static int qca_disable_soc_logging(struct hci_dev *hdev)627{628	struct sk_buff *skb;629	u8 cmd[2];630	int err;631 632	cmd[0] = QCA_DISABLE_LOGGING_SUB_OP;633	cmd[1] = 0x00;634	skb = __hci_cmd_sync_ev(hdev, QCA_DISABLE_LOGGING, sizeof(cmd), cmd,635				HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);636	if (IS_ERR(skb)) {637		err = PTR_ERR(skb);638		bt_dev_err(hdev, "QCA Failed to disable soc logging(%d)", err);639		return err;640	}641 642	kfree_skb(skb);643 644	return 0;645}646 647int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)648{649	struct sk_buff *skb;650	u8 cmd[9];651	int err;652 653	cmd[0] = EDL_NVM_ACCESS_SET_REQ_CMD;654	cmd[1] = 0x02; 			/* TAG ID */655	cmd[2] = sizeof(bdaddr_t);	/* size */656	memcpy(cmd + 3, bdaddr, sizeof(bdaddr_t));657	skb = __hci_cmd_sync_ev(hdev, EDL_NVM_ACCESS_OPCODE, sizeof(cmd), cmd,658				HCI_EV_VENDOR, HCI_INIT_TIMEOUT);659	if (IS_ERR(skb)) {660		err = PTR_ERR(skb);661		bt_dev_err(hdev, "QCA Change address command failed (%d)", err);662		return err;663	}664 665	kfree_skb(skb);666 667	return 0;668}669EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);670 671static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *config)672{673	struct hci_rp_read_bd_addr *bda;674	struct sk_buff *skb;675	int err;676 677	if (bacmp(&hdev->public_addr, BDADDR_ANY))678		return 0;679 680	skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,681			     HCI_INIT_TIMEOUT);682	if (IS_ERR(skb)) {683		err = PTR_ERR(skb);684		bt_dev_err(hdev, "Failed to read device address (%d)", err);685		return err;686	}687 688	if (skb->len != sizeof(*bda)) {689		bt_dev_err(hdev, "Device address length mismatch");690		kfree_skb(skb);691		return -EIO;692	}693 694	bda = (struct hci_rp_read_bd_addr *)skb->data;695	if (!bacmp(&bda->bdaddr, &config->bdaddr))696		set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);697 698	kfree_skb(skb);699 700	return 0;701}702 703static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,704		struct qca_btsoc_version ver, u8 rom_ver, u16 bid)705{706	const char *variant;707 708	/* hsp gf chip */709	if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)710		variant = "g";711	else712		variant = "";713 714	if (bid == 0x0)715		snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant);716	else717		snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid);718}719 720static inline void qca_get_nvm_name_generic(struct qca_fw_config *cfg,721					    const char *stem, u8 rom_ver, u16 bid)722{723	if (bid == 0x0)724		snprintf(cfg->fwname, sizeof(cfg->fwname), "qca/%snv%02x.bin", stem, rom_ver);725	else if (bid & 0xff00)726		snprintf(cfg->fwname, sizeof(cfg->fwname),727			 "qca/%snv%02x.b%x", stem, rom_ver, bid);728	else729		snprintf(cfg->fwname, sizeof(cfg->fwname),730			 "qca/%snv%02x.b%02x", stem, rom_ver, bid);731}732 733int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,734		   enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,735		   const char *firmware_name)736{737	struct qca_fw_config config = {};738	int err;739	u8 rom_ver = 0;740	u32 soc_ver;741	u16 boardid = 0;742 743	bt_dev_dbg(hdev, "QCA setup on UART");744 745	soc_ver = get_soc_ver(ver.soc_id, ver.rom_ver);746 747	bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);748 749	config.user_baud_rate = baudrate;750 751	/* Firmware files to download are based on ROM version.752	 * ROM version is derived from last two bytes of soc_ver.753	 */754	if (soc_type == QCA_WCN3988)755		rom_ver = ((soc_ver & 0x00000f00) >> 0x05) | (soc_ver & 0x0000000f);756	else757		rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f);758 759	if (soc_type == QCA_WCN6750)760		qca_send_patch_config_cmd(hdev);761 762	/* Download rampatch file */763	config.type = TLV_TYPE_PATCH;764	switch (soc_type) {765	case QCA_WCN3990:766	case QCA_WCN3991:767	case QCA_WCN3998:768		snprintf(config.fwname, sizeof(config.fwname),769			 "qca/crbtfw%02x.tlv", rom_ver);770		break;771	case QCA_WCN3988:772		snprintf(config.fwname, sizeof(config.fwname),773			 "qca/apbtfw%02x.tlv", rom_ver);774		break;775	case QCA_QCA2066:776		snprintf(config.fwname, sizeof(config.fwname),777			 "qca/hpbtfw%02x.tlv", rom_ver);778		break;779	case QCA_QCA6390:780		snprintf(config.fwname, sizeof(config.fwname),781			 "qca/htbtfw%02x.tlv", rom_ver);782		break;783	case QCA_WCN6750:784		/* Choose mbn file by default.If mbn file is not found785		 * then choose tlv file786		 */787		config.type = ELF_TYPE_PATCH;788		snprintf(config.fwname, sizeof(config.fwname),789			 "qca/msbtfw%02x.mbn", rom_ver);790		break;791	case QCA_WCN6855:792		snprintf(config.fwname, sizeof(config.fwname),793			 "qca/hpbtfw%02x.tlv", rom_ver);794		break;795	case QCA_WCN7850:796		snprintf(config.fwname, sizeof(config.fwname),797			 "qca/hmtbtfw%02x.tlv", rom_ver);798		break;799	default:800		snprintf(config.fwname, sizeof(config.fwname),801			 "qca/rampatch_%08x.bin", soc_ver);802	}803 804	err = qca_download_firmware(hdev, &config, soc_type, rom_ver);805	if (err < 0) {806		bt_dev_err(hdev, "QCA Failed to download patch (%d)", err);807		return err;808	}809 810	/* Give the controller some time to get ready to receive the NVM */811	msleep(10);812 813	if (soc_type == QCA_QCA2066 || soc_type == QCA_WCN7850)814		qca_read_fw_board_id(hdev, &boardid);815 816	/* Download NVM configuration */817	config.type = TLV_TYPE_NVM;818	if (firmware_name) {819		snprintf(config.fwname, sizeof(config.fwname),820			 "qca/%s", firmware_name);821	} else {822		switch (soc_type) {823		case QCA_WCN3990:824		case QCA_WCN3991:825		case QCA_WCN3998:826			if (le32_to_cpu(ver.soc_id) == QCA_WCN3991_SOC_ID) {827				snprintf(config.fwname, sizeof(config.fwname),828					 "qca/crnv%02xu.bin", rom_ver);829			} else {830				snprintf(config.fwname, sizeof(config.fwname),831					 "qca/crnv%02x.bin", rom_ver);832			}833			break;834		case QCA_WCN3988:835			snprintf(config.fwname, sizeof(config.fwname),836				 "qca/apnv%02x.bin", rom_ver);837			break;838		case QCA_QCA2066:839			qca_generate_hsp_nvm_name(config.fwname,840				sizeof(config.fwname), ver, rom_ver, boardid);841			break;842		case QCA_QCA6390:843			snprintf(config.fwname, sizeof(config.fwname),844				 "qca/htnv%02x.bin", rom_ver);845			break;846		case QCA_WCN6750:847			snprintf(config.fwname, sizeof(config.fwname),848				 "qca/msnv%02x.bin", rom_ver);849			break;850		case QCA_WCN6855:851			snprintf(config.fwname, sizeof(config.fwname),852				 "qca/hpnv%02x.bin", rom_ver);853			break;854		case QCA_WCN7850:855			qca_get_nvm_name_generic(&config, "hmt", rom_ver, boardid);856			break;857 858		default:859			snprintf(config.fwname, sizeof(config.fwname),860				 "qca/nvm_%08x.bin", soc_ver);861		}862	}863 864	err = qca_download_firmware(hdev, &config, soc_type, rom_ver);865	if (err < 0) {866		bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err);867		return err;868	}869 870	switch (soc_type) {871	case QCA_WCN3991:872	case QCA_QCA2066:873	case QCA_QCA6390:874	case QCA_WCN6750:875	case QCA_WCN6855:876	case QCA_WCN7850:877		err = qca_disable_soc_logging(hdev);878		if (err < 0)879			return err;880		break;881	default:882		break;883	}884 885	/* WCN399x and WCN6750 supports the Microsoft vendor extension with 0xFD70 as the886	 * VsMsftOpCode.887	 */888	switch (soc_type) {889	case QCA_WCN3988:890	case QCA_WCN3990:891	case QCA_WCN3991:892	case QCA_WCN3998:893	case QCA_WCN6750:894		hci_set_msft_opcode(hdev, 0xFD70);895		break;896	default:897		break;898	}899 900	/* Perform HCI reset */901	err = qca_send_reset(hdev);902	if (err < 0) {903		bt_dev_err(hdev, "QCA Failed to run HCI_RESET (%d)", err);904		return err;905	}906 907	switch (soc_type) {908	case QCA_WCN3991:909	case QCA_WCN6750:910	case QCA_WCN6855:911	case QCA_WCN7850:912		/* get fw build info */913		err = qca_read_fw_build_info(hdev);914		if (err < 0)915			return err;916		break;917	default:918		break;919	}920 921	err = qca_check_bdaddr(hdev, &config);922	if (err)923		return err;924 925	bt_dev_info(hdev, "QCA setup on UART is completed");926 927	return 0;928}929EXPORT_SYMBOL_GPL(qca_uart_setup);930 931int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)932{933	bdaddr_t bdaddr_swapped;934	struct sk_buff *skb;935	int err;936 937	baswap(&bdaddr_swapped, bdaddr);938 939	skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6,940				&bdaddr_swapped, HCI_EV_VENDOR,941				HCI_INIT_TIMEOUT);942	if (IS_ERR(skb)) {943		err = PTR_ERR(skb);944		bt_dev_err(hdev, "QCA Change address cmd failed (%d)", err);945		return err;946	}947 948	kfree_skb(skb);949 950	return 0;951}952EXPORT_SYMBOL_GPL(qca_set_bdaddr);953 954 955MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>");956MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family");957MODULE_LICENSE("GPL");958