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

1 // SPDX-License-Identifier: GPL-2.0-or-later
117 .hw_info = "rtl8723bs" },
127 /* 8723CS-CG */
137 .hw_info = "rtl8723cs-cg" },
139 /* 8723CS-VF */
149 .hw_info = "rtl8723cs-vf" },
151 /* 8723CS-XX */
355 if (skb->len != sizeof(struct hci_rp_read_local_version)) { in btrtl_read_local_version()
358 return ERR_PTR(-EIO); in btrtl_read_local_version()
377 if (skb->len != sizeof(*rom_version)) { in rtl_read_rom_version()
380 return -EIO; in rtl_read_rom_version()
383 rom_version = (struct rtl_rom_version_evt *)skb->data; in rtl_read_rom_version()
385 rom_version->status, rom_version->version); in rtl_read_rom_version()
387 *version = rom_version->version; in rtl_read_rom_version()
407 if (skb->len != 3 || skb->data[0]) { in btrtl_vendor_read_reg16()
410 return -EIO; in btrtl_vendor_read_reg16()
414 memcpy(rp, skb->data + 1, 2); in btrtl_vendor_read_reg16()
423 void *data = iov->data; in rtl_iov_pull_data()
425 if (iov->len < len) in rtl_iov_pull_data()
428 iov->data += len; in rtl_iov_pull_data()
429 iov->len -= len; in rtl_iov_pull_data()
441 list_for_each_safe(pos, next, &btrtl_dev->patch_subsecs) { in btrtl_insert_ordered_subsec()
443 if (subsec->prio >= node->prio) in btrtl_insert_ordered_subsec()
446 __list_add(&node->list, pos->prev, pos); in btrtl_insert_ordered_subsec()
469 return -EINVAL; in btrtl_parse_section()
470 num_subsecs = le16_to_cpu(hdr->num); in btrtl_parse_section()
476 subsec_len = le32_to_cpu(common_subsec->len); in btrtl_parse_section()
479 common_subsec->eco, subsec_len); in btrtl_parse_section()
485 if (common_subsec->eco != btrtl_dev->rom_version + 1) in btrtl_parse_section()
491 if (sec_hdr->key_id != btrtl_dev->key_id) in btrtl_parse_section()
498 return -ENOMEM; in btrtl_parse_section()
499 subsec->opcode = opcode; in btrtl_parse_section()
500 subsec->prio = common_subsec->prio; in btrtl_parse_section()
501 subsec->len = subsec_len; in btrtl_parse_section()
502 subsec->data = ptr; in btrtl_parse_section()
527 .data = btrtl_dev->fw_data, in rtlbt_parse_firmware_v2()
528 .len = btrtl_dev->fw_len - 7, /* Cut the tail */ in rtlbt_parse_firmware_v2()
533 return -EIO; in rtlbt_parse_firmware_v2()
538 btrtl_dev->key_id = key_id; in rtlbt_parse_firmware_v2()
542 return -EINVAL; in rtlbt_parse_firmware_v2()
543 num_sections = le32_to_cpu(hdr->num_sections); in rtlbt_parse_firmware_v2()
545 rtl_dev_dbg(hdev, "FW version %08x-%08x", *((u32 *)hdr->fw_version), in rtlbt_parse_firmware_v2()
546 *((u32 *)(hdr->fw_version + 4))); in rtlbt_parse_firmware_v2()
552 section_len = le32_to_cpu(section->len); in rtlbt_parse_firmware_v2()
553 opcode = le32_to_cpu(section->opcode); in rtlbt_parse_firmware_v2()
555 rtl_dev_dbg(hdev, "opcode 0x%04x", section->opcode); in rtlbt_parse_firmware_v2()
592 return -ENODATA; in rtlbt_parse_firmware_v2()
597 return -ENOMEM; in rtlbt_parse_firmware_v2()
600 list_for_each_entry_safe(entry, tmp, &btrtl_dev->patch_subsecs, list) { in rtlbt_parse_firmware_v2()
602 entry->opcode, entry->data, entry->len); in rtlbt_parse_firmware_v2()
603 memcpy(ptr + len, entry->data, entry->len); in rtlbt_parse_firmware_v2()
604 len += entry->len; in rtlbt_parse_firmware_v2()
608 return -EPERM; in rtlbt_parse_firmware_v2()
625 int project_id = -1; in rtlbt_parse_firmware()
650 if (btrtl_dev->fw_len <= 8) in rtlbt_parse_firmware()
651 return -EINVAL; in rtlbt_parse_firmware()
653 if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) in rtlbt_parse_firmware()
656 else if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE_V2, 8)) in rtlbt_parse_firmware()
660 return -EINVAL; in rtlbt_parse_firmware()
662 if (btrtl_dev->fw_len < min_size) in rtlbt_parse_firmware()
663 return -EINVAL; in rtlbt_parse_firmware()
665 fwptr = btrtl_dev->fw_data + btrtl_dev->fw_len - sizeof(extension_sig); in rtlbt_parse_firmware()
668 return -EINVAL; in rtlbt_parse_firmware()
674 * Once we have that, we double-check that project_id is suitable in rtlbt_parse_firmware()
677 while (fwptr >= btrtl_dev->fw_data + (sizeof(*epatch_info) + 3)) { in rtlbt_parse_firmware()
678 opcode = *--fwptr; in rtlbt_parse_firmware()
679 length = *--fwptr; in rtlbt_parse_firmware()
680 data = *--fwptr; in rtlbt_parse_firmware()
689 return -EINVAL; in rtlbt_parse_firmware()
697 fwptr -= length; in rtlbt_parse_firmware()
702 return -EINVAL; in rtlbt_parse_firmware()
708 btrtl_dev->project_id = project_id; in rtlbt_parse_firmware()
715 return -EINVAL; in rtlbt_parse_firmware()
718 if (btrtl_dev->ic_info->lmp_subver != in rtlbt_parse_firmware()
722 btrtl_dev->ic_info->lmp_subver); in rtlbt_parse_firmware()
723 return -EINVAL; in rtlbt_parse_firmware()
726 if (memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8) != 0) { in rtlbt_parse_firmware()
727 if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE_V2, 8)) in rtlbt_parse_firmware()
730 return -EINVAL; in rtlbt_parse_firmware()
733 epatch_info = (struct rtl_epatch_header *)btrtl_dev->fw_data; in rtlbt_parse_firmware()
734 num_patches = le16_to_cpu(epatch_info->num_patches); in rtlbt_parse_firmware()
737 le32_to_cpu(epatch_info->fw_version), num_patches); in rtlbt_parse_firmware()
738 coredump_info->rtl_dump.fw_version = le32_to_cpu(epatch_info->fw_version); in rtlbt_parse_firmware()
747 if (btrtl_dev->fw_len < min_size) in rtlbt_parse_firmware()
748 return -EINVAL; in rtlbt_parse_firmware()
750 chip_id_base = btrtl_dev->fw_data + sizeof(struct rtl_epatch_header); in rtlbt_parse_firmware()
756 if (chip_id == btrtl_dev->rom_version + 1) { in rtlbt_parse_firmware()
767 btrtl_dev->rom_version); in rtlbt_parse_firmware()
768 return -EINVAL; in rtlbt_parse_firmware()
773 if (btrtl_dev->fw_len < min_size) in rtlbt_parse_firmware()
774 return -EINVAL; in rtlbt_parse_firmware()
782 return -ENOMEM; in rtlbt_parse_firmware()
784 memcpy(buf, btrtl_dev->fw_data + patch_offset, patch_length - 4); in rtlbt_parse_firmware()
785 memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4); in rtlbt_parse_firmware()
805 return -ENOMEM; in rtl_download_firmware()
810 dl_cmd->index = j++; in rtl_download_firmware()
811 if (dl_cmd->index == 0x7f) in rtl_download_firmware()
814 if (i == (frag_num - 1)) { in rtl_download_firmware()
815 dl_cmd->index |= 0x80; /* data end */ in rtl_download_firmware()
819 frag_num, dl_cmd->index); in rtl_download_firmware()
820 memcpy(dl_cmd->data, data, frag_len); in rtl_download_firmware()
832 if (skb->len != sizeof(struct rtl_download_response)) { in rtl_download_firmware()
835 ret = -EIO; in rtl_download_firmware()
850 rp = (struct hci_rp_read_local_version *)skb->data; in rtl_download_firmware()
852 __le16_to_cpu(rp->hci_rev), __le16_to_cpu(rp->lmp_subver)); in rtl_download_firmware()
866 ret = request_firmware(&fw, name, &hdev->dev); in rtl_load_file()
869 ret = fw->size; in rtl_load_file()
870 *buff = kvmalloc(fw->size, GFP_KERNEL); in rtl_load_file()
872 memcpy(*buff, fw->data, ret); in rtl_load_file()
874 ret = -ENOMEM; in rtl_load_file()
884 if (btrtl_dev->fw_len < 8) in btrtl_setup_rtl8723a()
885 return -EINVAL; in btrtl_setup_rtl8723a()
890 if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) { in btrtl_setup_rtl8723a()
892 return -EINVAL; in btrtl_setup_rtl8723a()
895 return rtl_download_firmware(hdev, btrtl_dev->fw_data, in btrtl_setup_rtl8723a()
896 btrtl_dev->fw_len); in btrtl_setup_rtl8723a()
910 if (btrtl_dev->cfg_len > 0) { in btrtl_setup_rtl8723b()
911 tbuff = kvzalloc(ret + btrtl_dev->cfg_len, GFP_KERNEL); in btrtl_setup_rtl8723b()
913 ret = -ENOMEM; in btrtl_setup_rtl8723b()
920 memcpy(tbuff + ret, btrtl_dev->cfg_data, btrtl_dev->cfg_len); in btrtl_setup_rtl8723b()
921 ret += btrtl_dev->cfg_len; in btrtl_setup_rtl8723b()
926 rtl_dev_info(hdev, "cfg_sz %d, total sz %d", btrtl_dev->cfg_len, ret); in btrtl_setup_rtl8723b()
947 if (coredump_info->rtl_dump.controller) in btrtl_dmp_hdr()
949 coredump_info->rtl_dump.controller); in btrtl_dmp_hdr()
955 coredump_info->rtl_dump.fw_version); in btrtl_dmp_hdr()
958 snprintf(buf, sizeof(buf), "Driver: %s\n", coredump_info->rtl_dump.driver_name); in btrtl_dmp_hdr()
975 coredump_info->rtl_dump.driver_name = driver_name; in btrtl_set_driver_name()
1009 return -EIO; in rtl_read_chip_type()
1013 chip_type->status, chip_type->type); in rtl_read_chip_type()
1015 *type = chip_type->type & 0x0f; in rtl_read_chip_type()
1025 kvfree(btrtl_dev->fw_data); in btrtl_free()
1026 kvfree(btrtl_dev->cfg_data); in btrtl_free()
1028 list_for_each_entry_safe(entry, tmp, &btrtl_dev->patch_subsecs, list) { in btrtl_free()
1029 list_del(&entry->list); in btrtl_free()
1054 ret = -ENOMEM; in btrtl_initialize()
1058 INIT_LIST_HEAD(&btrtl_dev->patch_subsecs); in btrtl_initialize()
1076 btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, in btrtl_initialize()
1077 hci_ver, hdev->bus, in btrtl_initialize()
1089 resp = (struct hci_rp_read_local_version *)skb->data; in btrtl_initialize()
1091 hci_ver = resp->hci_ver; in btrtl_initialize()
1092 hci_rev = le16_to_cpu(resp->hci_rev); in btrtl_initialize()
1093 lmp_ver = resp->lmp_ver; in btrtl_initialize()
1094 lmp_subver = le16_to_cpu(resp->lmp_subver); in btrtl_initialize()
1104 btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver, in btrtl_initialize()
1105 hdev->bus, chip_type); in btrtl_initialize()
1112 if (!btrtl_dev->ic_info && !btrtl_dev->drop_fw) in btrtl_initialize()
1113 btrtl_dev->drop_fw = true; in btrtl_initialize()
1115 btrtl_dev->drop_fw = false; in btrtl_initialize()
1117 if (btrtl_dev->drop_fw) { in btrtl_initialize()
1123 cmd->opcode = cpu_to_le16(0xfc66); in btrtl_initialize()
1124 cmd->plen = 0; in btrtl_initialize()
1128 ret = hdev->send(hdev, skb); in btrtl_initialize()
1143 if (!btrtl_dev->ic_info) { in btrtl_initialize()
1149 if (btrtl_dev->ic_info->has_rom_version) { in btrtl_initialize()
1150 ret = rtl_read_rom_version(hdev, &btrtl_dev->rom_version); in btrtl_initialize()
1155 if (!btrtl_dev->ic_info->fw_name) { in btrtl_initialize()
1156 ret = -ENOMEM; in btrtl_initialize()
1160 btrtl_dev->fw_len = -EIO; in btrtl_initialize()
1163 btrtl_dev->ic_info->fw_name); in btrtl_initialize()
1164 btrtl_dev->fw_len = rtl_load_file(hdev, fw_name, in btrtl_initialize()
1165 &btrtl_dev->fw_data); in btrtl_initialize()
1168 if (btrtl_dev->fw_len < 0) { in btrtl_initialize()
1170 btrtl_dev->ic_info->fw_name); in btrtl_initialize()
1171 btrtl_dev->fw_len = rtl_load_file(hdev, fw_name, in btrtl_initialize()
1172 &btrtl_dev->fw_data); in btrtl_initialize()
1175 if (btrtl_dev->fw_len < 0) { in btrtl_initialize()
1177 btrtl_dev->ic_info->fw_name); in btrtl_initialize()
1178 ret = btrtl_dev->fw_len; in btrtl_initialize()
1182 if (btrtl_dev->ic_info->cfg_name) { in btrtl_initialize()
1184 snprintf(cfg_name, sizeof(cfg_name), "%s-%s.bin", in btrtl_initialize()
1185 btrtl_dev->ic_info->cfg_name, postfix); in btrtl_initialize()
1188 btrtl_dev->ic_info->cfg_name); in btrtl_initialize()
1190 btrtl_dev->cfg_len = rtl_load_file(hdev, cfg_name, in btrtl_initialize()
1191 &btrtl_dev->cfg_data); in btrtl_initialize()
1192 if (btrtl_dev->ic_info->config_needed && in btrtl_initialize()
1193 btrtl_dev->cfg_len <= 0) { in btrtl_initialize()
1195 btrtl_dev->ic_info->cfg_name); in btrtl_initialize()
1196 ret = btrtl_dev->cfg_len; in btrtl_initialize()
1204 if (btrtl_dev->ic_info->has_msft_ext) in btrtl_initialize()
1207 if (btrtl_dev->ic_info) in btrtl_initialize()
1208 coredump_info->rtl_dump.controller = btrtl_dev->ic_info->hw_info; in btrtl_initialize()
1230 if (!btrtl_dev->ic_info) { in btrtl_download_firmware()
1236 switch (btrtl_dev->ic_info->lmp_subver) { in btrtl_download_firmware()
1266 set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); in btrtl_set_quirks()
1268 /* Enable central-peripheral role (able to create new connections with in btrtl_set_quirks()
1272 switch (btrtl_dev->project_id) { in btrtl_set_quirks()
1278 set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); in btrtl_set_quirks()
1279 set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); in btrtl_set_quirks()
1284 if (btrtl_dev->project_id == CHIP_ID_8852C) in btrtl_set_quirks()
1287 if (btrtl_dev->project_id == CHIP_ID_8852A || in btrtl_set_quirks()
1288 btrtl_dev->project_id == CHIP_ID_8852C) in btrtl_set_quirks()
1289 set_bit(HCI_QUIRK_USE_MSFT_EXT_ADDRESS_FILTER, &hdev->quirks); in btrtl_set_quirks()
1294 rtl_dev_dbg(hdev, "Central-peripheral role not enabled."); in btrtl_set_quirks()
1299 if (!btrtl_dev->ic_info) in btrtl_set_quirks()
1302 switch (btrtl_dev->ic_info->lmp_subver) { in btrtl_set_quirks()
1305 * but it doesn't support any features from page 2 - in btrtl_set_quirks()
1309 &hdev->quirks); in btrtl_set_quirks()
1340 /* According to the vendor driver, BT must be reset on close to avoid in btrtl_shutdown_realtek()
1402 total_data_len = btrtl_dev->cfg_len - sizeof(*config); in btrtl_get_uart_settings()
1405 return -EINVAL; in btrtl_get_uart_settings()
1408 config = (struct rtl_vendor_config *)btrtl_dev->cfg_data; in btrtl_get_uart_settings()
1409 if (le32_to_cpu(config->signature) != RTL_CONFIG_MAGIC) { in btrtl_get_uart_settings()
1411 return -EINVAL; in btrtl_get_uart_settings()
1414 if (total_data_len < le16_to_cpu(config->total_len)) { in btrtl_get_uart_settings()
1416 return -EINVAL; in btrtl_get_uart_settings()
1420 entry = ((void *)config->entry) + i; in btrtl_get_uart_settings()
1422 switch (le16_to_cpu(entry->offset)) { in btrtl_get_uart_settings()
1424 if (entry->len < sizeof(*device_baudrate)) { in btrtl_get_uart_settings()
1426 return -EINVAL; in btrtl_get_uart_settings()
1429 *device_baudrate = get_unaligned_le32(entry->data); in btrtl_get_uart_settings()
1433 if (entry->len >= 13) in btrtl_get_uart_settings()
1434 *flow_control = !!(entry->data[12] & BIT(2)); in btrtl_get_uart_settings()
1443 le16_to_cpu(entry->offset), entry->len); in btrtl_get_uart_settings()
1447 i += sizeof(*entry) + entry->len; in btrtl_get_uart_settings()
1452 return -ENOENT; in btrtl_get_uart_settings()