Lines Matching +full:rtl8723bs +full:- +full:bt

1 // SPDX-License-Identifier: GPL-2.0-or-later
120 .hw_info = "rtl8723bs" },
130 /* 8723CS-CG */
140 .hw_info = "rtl8723cs-cg" },
142 /* 8723CS-VF */
152 .hw_info = "rtl8723cs-vf" },
154 /* 8723CS-XX */
323 /* 8852BT/8852BE-VT */
376 if (skb->len != sizeof(struct hci_rp_read_local_version)) { in btrtl_read_local_version()
379 return ERR_PTR(-EIO); in btrtl_read_local_version()
398 if (skb->len != sizeof(*rom_version)) { in rtl_read_rom_version()
401 return -EIO; in rtl_read_rom_version()
404 rom_version = (struct rtl_rom_version_evt *)skb->data; in rtl_read_rom_version()
406 rom_version->status, rom_version->version); in rtl_read_rom_version()
408 *version = rom_version->version; in rtl_read_rom_version()
428 if (skb->len != 3 || skb->data[0]) { in btrtl_vendor_read_reg16()
431 return -EIO; in btrtl_vendor_read_reg16()
435 memcpy(rp, skb->data + 1, 2); in btrtl_vendor_read_reg16()
444 void *data = iov->data; in rtl_iov_pull_data()
446 if (iov->len < len) in rtl_iov_pull_data()
449 iov->data += len; in rtl_iov_pull_data()
450 iov->len -= len; in rtl_iov_pull_data()
462 list_for_each_safe(pos, next, &btrtl_dev->patch_subsecs) { in btrtl_insert_ordered_subsec()
464 if (subsec->prio >= node->prio) in btrtl_insert_ordered_subsec()
467 __list_add(&node->list, pos->prev, pos); in btrtl_insert_ordered_subsec()
490 return -EINVAL; in btrtl_parse_section()
491 num_subsecs = le16_to_cpu(hdr->num); in btrtl_parse_section()
497 subsec_len = le32_to_cpu(common_subsec->len); in btrtl_parse_section()
500 common_subsec->eco, subsec_len); in btrtl_parse_section()
506 if (common_subsec->eco != btrtl_dev->rom_version + 1) in btrtl_parse_section()
512 if (sec_hdr->key_id != btrtl_dev->key_id) in btrtl_parse_section()
519 return -ENOMEM; in btrtl_parse_section()
520 subsec->opcode = opcode; in btrtl_parse_section()
521 subsec->prio = common_subsec->prio; in btrtl_parse_section()
522 subsec->len = subsec_len; in btrtl_parse_section()
523 subsec->data = ptr; in btrtl_parse_section()
548 .data = btrtl_dev->fw_data, in rtlbt_parse_firmware_v2()
549 .len = btrtl_dev->fw_len - 7, /* Cut the tail */ in rtlbt_parse_firmware_v2()
554 return -EIO; in rtlbt_parse_firmware_v2()
559 btrtl_dev->key_id = key_id; in rtlbt_parse_firmware_v2()
563 return -EINVAL; in rtlbt_parse_firmware_v2()
564 num_sections = le32_to_cpu(hdr->num_sections); in rtlbt_parse_firmware_v2()
566 rtl_dev_dbg(hdev, "FW version %08x-%08x", *((u32 *)hdr->fw_version), in rtlbt_parse_firmware_v2()
567 *((u32 *)(hdr->fw_version + 4))); in rtlbt_parse_firmware_v2()
573 section_len = le32_to_cpu(section->len); in rtlbt_parse_firmware_v2()
574 opcode = le32_to_cpu(section->opcode); in rtlbt_parse_firmware_v2()
576 rtl_dev_dbg(hdev, "opcode 0x%04x", section->opcode); in rtlbt_parse_firmware_v2()
613 return -ENODATA; in rtlbt_parse_firmware_v2()
618 return -ENOMEM; in rtlbt_parse_firmware_v2()
621 list_for_each_entry_safe(entry, tmp, &btrtl_dev->patch_subsecs, list) { in rtlbt_parse_firmware_v2()
623 entry->opcode, entry->data, entry->len); in rtlbt_parse_firmware_v2()
624 memcpy(ptr + len, entry->data, entry->len); in rtlbt_parse_firmware_v2()
625 len += entry->len; in rtlbt_parse_firmware_v2()
629 return -EPERM; in rtlbt_parse_firmware_v2()
646 int project_id = -1; in rtlbt_parse_firmware()
670 { RTL_ROM_LMP_8852A, 47 }, /* 8852BT */ in rtlbt_parse_firmware()
673 if (btrtl_dev->fw_len <= 8) in rtlbt_parse_firmware()
674 return -EINVAL; in rtlbt_parse_firmware()
676 if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) in rtlbt_parse_firmware()
679 else if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE_V2, 8)) in rtlbt_parse_firmware()
683 return -EINVAL; in rtlbt_parse_firmware()
685 if (btrtl_dev->fw_len < min_size) in rtlbt_parse_firmware()
686 return -EINVAL; in rtlbt_parse_firmware()
688 fwptr = btrtl_dev->fw_data + btrtl_dev->fw_len - sizeof(extension_sig); in rtlbt_parse_firmware()
691 return -EINVAL; in rtlbt_parse_firmware()
697 * Once we have that, we double-check that project_id is suitable in rtlbt_parse_firmware()
700 while (fwptr >= btrtl_dev->fw_data + (sizeof(*epatch_info) + 3)) { in rtlbt_parse_firmware()
701 opcode = *--fwptr; in rtlbt_parse_firmware()
702 length = *--fwptr; in rtlbt_parse_firmware()
703 data = *--fwptr; in rtlbt_parse_firmware()
712 return -EINVAL; in rtlbt_parse_firmware()
720 fwptr -= length; in rtlbt_parse_firmware()
725 return -EINVAL; in rtlbt_parse_firmware()
731 btrtl_dev->project_id = project_id; in rtlbt_parse_firmware()
738 return -EINVAL; in rtlbt_parse_firmware()
741 if (btrtl_dev->ic_info->lmp_subver != in rtlbt_parse_firmware()
745 btrtl_dev->ic_info->lmp_subver); in rtlbt_parse_firmware()
746 return -EINVAL; in rtlbt_parse_firmware()
749 if (memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8) != 0) { in rtlbt_parse_firmware()
750 if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE_V2, 8)) in rtlbt_parse_firmware()
753 return -EINVAL; in rtlbt_parse_firmware()
756 epatch_info = (struct rtl_epatch_header *)btrtl_dev->fw_data; in rtlbt_parse_firmware()
757 num_patches = le16_to_cpu(epatch_info->num_patches); in rtlbt_parse_firmware()
760 le32_to_cpu(epatch_info->fw_version), num_patches); in rtlbt_parse_firmware()
761 coredump_info->rtl_dump.fw_version = le32_to_cpu(epatch_info->fw_version); in rtlbt_parse_firmware()
770 if (btrtl_dev->fw_len < min_size) in rtlbt_parse_firmware()
771 return -EINVAL; in rtlbt_parse_firmware()
773 chip_id_base = btrtl_dev->fw_data + sizeof(struct rtl_epatch_header); in rtlbt_parse_firmware()
779 if (chip_id == btrtl_dev->rom_version + 1) { in rtlbt_parse_firmware()
790 btrtl_dev->rom_version); in rtlbt_parse_firmware()
791 return -EINVAL; in rtlbt_parse_firmware()
796 if (btrtl_dev->fw_len < min_size) in rtlbt_parse_firmware()
797 return -EINVAL; in rtlbt_parse_firmware()
805 return -ENOMEM; in rtlbt_parse_firmware()
807 memcpy(buf, btrtl_dev->fw_data + patch_offset, patch_length - 4); in rtlbt_parse_firmware()
808 memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4); in rtlbt_parse_firmware()
828 return -ENOMEM; in rtl_download_firmware()
833 dl_cmd->index = j++; in rtl_download_firmware()
834 if (dl_cmd->index == 0x7f) in rtl_download_firmware()
837 if (i == (frag_num - 1)) { in rtl_download_firmware()
838 dl_cmd->index |= 0x80; /* data end */ in rtl_download_firmware()
842 frag_num, dl_cmd->index); in rtl_download_firmware()
843 memcpy(dl_cmd->data, data, frag_len); in rtl_download_firmware()
855 if (skb->len != sizeof(struct rtl_download_response)) { in rtl_download_firmware()
858 ret = -EIO; in rtl_download_firmware()
873 rp = (struct hci_rp_read_local_version *)skb->data; in rtl_download_firmware()
875 __le16_to_cpu(rp->hci_rev), __le16_to_cpu(rp->lmp_subver)); in rtl_download_firmware()
889 ret = request_firmware(&fw, name, &hdev->dev); in rtl_load_file()
892 ret = fw->size; in rtl_load_file()
893 *buff = kvmemdup(fw->data, fw->size, GFP_KERNEL); in rtl_load_file()
895 ret = -ENOMEM; in rtl_load_file()
905 if (btrtl_dev->fw_len < 8) in btrtl_setup_rtl8723a()
906 return -EINVAL; in btrtl_setup_rtl8723a()
911 if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) { in btrtl_setup_rtl8723a()
913 return -EINVAL; in btrtl_setup_rtl8723a()
916 return rtl_download_firmware(hdev, btrtl_dev->fw_data, in btrtl_setup_rtl8723a()
917 btrtl_dev->fw_len); in btrtl_setup_rtl8723a()
931 if (btrtl_dev->cfg_len > 0) { in btrtl_setup_rtl8723b()
932 tbuff = kvzalloc(ret + btrtl_dev->cfg_len, GFP_KERNEL); in btrtl_setup_rtl8723b()
934 ret = -ENOMEM; in btrtl_setup_rtl8723b()
941 memcpy(tbuff + ret, btrtl_dev->cfg_data, btrtl_dev->cfg_len); in btrtl_setup_rtl8723b()
942 ret += btrtl_dev->cfg_len; in btrtl_setup_rtl8723b()
947 rtl_dev_info(hdev, "cfg_sz %d, total sz %d", btrtl_dev->cfg_len, ret); in btrtl_setup_rtl8723b()
968 if (coredump_info->rtl_dump.controller) in btrtl_dmp_hdr()
970 coredump_info->rtl_dump.controller); in btrtl_dmp_hdr()
976 coredump_info->rtl_dump.fw_version); in btrtl_dmp_hdr()
979 snprintf(buf, sizeof(buf), "Driver: %s\n", coredump_info->rtl_dump.driver_name); in btrtl_dmp_hdr()
996 coredump_info->rtl_dump.driver_name = driver_name; in btrtl_set_driver_name()
1030 return -EIO; in rtl_read_chip_type()
1034 chip_type->status, chip_type->type); in rtl_read_chip_type()
1036 *type = chip_type->type & 0x0f; in rtl_read_chip_type()
1046 kvfree(btrtl_dev->fw_data); in btrtl_free()
1047 kvfree(btrtl_dev->cfg_data); in btrtl_free()
1049 list_for_each_entry_safe(entry, tmp, &btrtl_dev->patch_subsecs, list) { in btrtl_free()
1050 list_del(&entry->list); in btrtl_free()
1075 ret = -ENOMEM; in btrtl_initialize()
1079 INIT_LIST_HEAD(&btrtl_dev->patch_subsecs); in btrtl_initialize()
1097 btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, in btrtl_initialize()
1098 hci_ver, hdev->bus, in btrtl_initialize()
1110 resp = (struct hci_rp_read_local_version *)skb->data; in btrtl_initialize()
1112 hci_ver = resp->hci_ver; in btrtl_initialize()
1113 hci_rev = le16_to_cpu(resp->hci_rev); in btrtl_initialize()
1114 lmp_ver = resp->lmp_ver; in btrtl_initialize()
1115 lmp_subver = le16_to_cpu(resp->lmp_subver); in btrtl_initialize()
1125 btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver, in btrtl_initialize()
1126 hdev->bus, chip_type); in btrtl_initialize()
1133 if (!btrtl_dev->ic_info && !btrtl_dev->drop_fw) in btrtl_initialize()
1134 btrtl_dev->drop_fw = true; in btrtl_initialize()
1136 btrtl_dev->drop_fw = false; in btrtl_initialize()
1138 if (btrtl_dev->drop_fw) { in btrtl_initialize()
1144 cmd->opcode = cpu_to_le16(0xfc66); in btrtl_initialize()
1145 cmd->plen = 0; in btrtl_initialize()
1149 ret = hdev->send(hdev, skb); in btrtl_initialize()
1164 if (!btrtl_dev->ic_info) { in btrtl_initialize()
1170 if (btrtl_dev->ic_info->has_rom_version) { in btrtl_initialize()
1171 ret = rtl_read_rom_version(hdev, &btrtl_dev->rom_version); in btrtl_initialize()
1176 if (!btrtl_dev->ic_info->fw_name) { in btrtl_initialize()
1177 ret = -ENOMEM; in btrtl_initialize()
1181 btrtl_dev->fw_len = -EIO; in btrtl_initialize()
1184 btrtl_dev->ic_info->fw_name); in btrtl_initialize()
1185 btrtl_dev->fw_len = rtl_load_file(hdev, fw_name, in btrtl_initialize()
1186 &btrtl_dev->fw_data); in btrtl_initialize()
1189 if (btrtl_dev->fw_len < 0) { in btrtl_initialize()
1191 btrtl_dev->ic_info->fw_name); in btrtl_initialize()
1192 btrtl_dev->fw_len = rtl_load_file(hdev, fw_name, in btrtl_initialize()
1193 &btrtl_dev->fw_data); in btrtl_initialize()
1196 if (btrtl_dev->fw_len < 0) { in btrtl_initialize()
1198 btrtl_dev->ic_info->fw_name); in btrtl_initialize()
1199 ret = btrtl_dev->fw_len; in btrtl_initialize()
1203 if (btrtl_dev->ic_info->cfg_name) { in btrtl_initialize()
1205 snprintf(cfg_name, sizeof(cfg_name), "%s-%s.bin", in btrtl_initialize()
1206 btrtl_dev->ic_info->cfg_name, postfix); in btrtl_initialize()
1209 btrtl_dev->ic_info->cfg_name); in btrtl_initialize()
1211 btrtl_dev->cfg_len = rtl_load_file(hdev, cfg_name, in btrtl_initialize()
1212 &btrtl_dev->cfg_data); in btrtl_initialize()
1213 if (btrtl_dev->ic_info->config_needed && in btrtl_initialize()
1214 btrtl_dev->cfg_len <= 0) { in btrtl_initialize()
1216 btrtl_dev->ic_info->cfg_name); in btrtl_initialize()
1217 ret = btrtl_dev->cfg_len; in btrtl_initialize()
1219 ret = -EINVAL; in btrtl_initialize()
1227 if (btrtl_dev->ic_info->has_msft_ext) in btrtl_initialize()
1230 if (btrtl_dev->ic_info) in btrtl_initialize()
1231 coredump_info->rtl_dump.controller = btrtl_dev->ic_info->hw_info; in btrtl_initialize()
1253 if (!btrtl_dev->ic_info) { in btrtl_download_firmware()
1259 switch (btrtl_dev->ic_info->lmp_subver) { in btrtl_download_firmware()
1290 set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); in btrtl_set_quirks()
1292 /* Enable central-peripheral role (able to create new connections with in btrtl_set_quirks()
1296 switch (btrtl_dev->project_id) { in btrtl_set_quirks()
1304 set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); in btrtl_set_quirks()
1309 if (btrtl_dev->project_id == CHIP_ID_8852C) in btrtl_set_quirks()
1312 if (btrtl_dev->project_id == CHIP_ID_8852A || in btrtl_set_quirks()
1313 btrtl_dev->project_id == CHIP_ID_8852B || in btrtl_set_quirks()
1314 btrtl_dev->project_id == CHIP_ID_8852C) in btrtl_set_quirks()
1315 set_bit(HCI_QUIRK_USE_MSFT_EXT_ADDRESS_FILTER, &hdev->quirks); in btrtl_set_quirks()
1320 rtl_dev_dbg(hdev, "Central-peripheral role not enabled."); in btrtl_set_quirks()
1325 if (!btrtl_dev->ic_info) in btrtl_set_quirks()
1328 switch (btrtl_dev->ic_info->lmp_subver) { in btrtl_set_quirks()
1331 * but it doesn't support any features from page 2 - in btrtl_set_quirks()
1335 &hdev->quirks); in btrtl_set_quirks()
1356 if (btrtl_dev->ic_info) { in btrtl_setup_realtek()
1359 btrtl_dev->ic_info->lmp_subver, in btrtl_setup_realtek()
1360 btrtl_dev->ic_info->hci_rev, in btrtl_setup_realtek()
1361 btrtl_dev->ic_info->hci_ver, in btrtl_setup_realtek()
1362 btrtl_dev->ic_info->hci_bus); in btrtl_setup_realtek()
1375 /* According to the vendor driver, BT must be reset on close to avoid in btrtl_shutdown_realtek()
1437 total_data_len = btrtl_dev->cfg_len - sizeof(*config); in btrtl_get_uart_settings()
1440 return -EINVAL; in btrtl_get_uart_settings()
1443 config = (struct rtl_vendor_config *)btrtl_dev->cfg_data; in btrtl_get_uart_settings()
1444 if (le32_to_cpu(config->signature) != RTL_CONFIG_MAGIC) { in btrtl_get_uart_settings()
1446 return -EINVAL; in btrtl_get_uart_settings()
1449 if (total_data_len < le16_to_cpu(config->total_len)) { in btrtl_get_uart_settings()
1451 return -EINVAL; in btrtl_get_uart_settings()
1455 entry = ((void *)config->entry) + i; in btrtl_get_uart_settings()
1457 switch (le16_to_cpu(entry->offset)) { in btrtl_get_uart_settings()
1459 if (entry->len < sizeof(*device_baudrate)) { in btrtl_get_uart_settings()
1461 return -EINVAL; in btrtl_get_uart_settings()
1464 *device_baudrate = get_unaligned_le32(entry->data); in btrtl_get_uart_settings()
1468 if (entry->len >= 13) in btrtl_get_uart_settings()
1469 *flow_control = !!(entry->data[12] & BIT(2)); in btrtl_get_uart_settings()
1478 le16_to_cpu(entry->offset), entry->len); in btrtl_get_uart_settings()
1482 i += sizeof(*entry) + entry->len; in btrtl_get_uart_settings()
1487 return -ENOENT; in btrtl_get_uart_settings()