^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Bluetooth support for Realtek devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015 Endless Mobile, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <net/bluetooth/bluetooth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <net/bluetooth/hci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "btrtl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define VERSION "0.1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define RTL_EPATCH_SIGNATURE "Realtech"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define RTL_ROM_LMP_3499 0x3499
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define RTL_ROM_LMP_8723A 0x1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define RTL_ROM_LMP_8723B 0x8723
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define RTL_ROM_LMP_8723D 0x8873
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define RTL_ROM_LMP_8821A 0x8821
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define RTL_ROM_LMP_8761A 0x8761
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define RTL_ROM_LMP_8822B 0x8822
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define RTL_ROM_LMP_8852A 0x8852
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define RTL_CONFIG_MAGIC 0x8723ab55
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define IC_MATCH_FL_LMPSUBV (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define IC_MATCH_FL_HCIREV (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define IC_MATCH_FL_HCIVER (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define IC_MATCH_FL_HCIBUS (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define IC_INFO(lmps, hcir) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .lmp_subver = (lmps), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .hci_rev = (hcir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct id_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) __u16 match_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) __u16 lmp_subver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __u16 hci_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) __u8 hci_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) __u8 hci_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) bool config_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) bool has_rom_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) char *fw_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) char *cfg_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct btrtl_device_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const struct id_table *ic_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u8 rom_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u8 *fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int fw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u8 *cfg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int cfg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static const struct id_table ic_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) { IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8723A, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .has_rom_version = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .fw_name = "rtl_bt/rtl8723a_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .cfg_name = NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) { IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_3499, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .has_rom_version = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .fw_name = "rtl_bt/rtl8723a_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .cfg_name = NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* 8723BS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .lmp_subver = RTL_ROM_LMP_8723B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .hci_rev = 0xb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .hci_ver = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .hci_bus = HCI_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .fw_name = "rtl_bt/rtl8723bs_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .cfg_name = "rtl_bt/rtl8723bs_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* 8723B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) { IC_INFO(RTL_ROM_LMP_8723B, 0xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .fw_name = "rtl_bt/rtl8723b_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .cfg_name = "rtl_bt/rtl8723b_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* 8723D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) { IC_INFO(RTL_ROM_LMP_8723B, 0xd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .fw_name = "rtl_bt/rtl8723d_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .cfg_name = "rtl_bt/rtl8723d_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* 8723DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .lmp_subver = RTL_ROM_LMP_8723B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .hci_rev = 0xd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .hci_ver = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .hci_bus = HCI_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .fw_name = "rtl_bt/rtl8723ds_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .cfg_name = "rtl_bt/rtl8723ds_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* 8723DU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { IC_INFO(RTL_ROM_LMP_8723D, 0x826C),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .fw_name = "rtl_bt/rtl8723d_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .cfg_name = "rtl_bt/rtl8723d_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* 8821A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) { IC_INFO(RTL_ROM_LMP_8821A, 0xa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .fw_name = "rtl_bt/rtl8821a_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .cfg_name = "rtl_bt/rtl8821a_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* 8821C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) { IC_INFO(RTL_ROM_LMP_8821A, 0xc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .fw_name = "rtl_bt/rtl8821c_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .cfg_name = "rtl_bt/rtl8821c_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* 8761A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { IC_INFO(RTL_ROM_LMP_8761A, 0xa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .fw_name = "rtl_bt/rtl8761a_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .cfg_name = "rtl_bt/rtl8761a_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* 8761B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { IC_INFO(RTL_ROM_LMP_8761A, 0xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .fw_name = "rtl_bt/rtl8761b_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .cfg_name = "rtl_bt/rtl8761b_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* 8822C with UART interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) IC_MATCH_FL_HCIBUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .lmp_subver = RTL_ROM_LMP_8822B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .hci_rev = 0x000c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .hci_ver = 0x0a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .hci_bus = HCI_UART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .fw_name = "rtl_bt/rtl8822cs_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .cfg_name = "rtl_bt/rtl8822cs_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* 8822C with USB interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { IC_INFO(RTL_ROM_LMP_8822B, 0xc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .fw_name = "rtl_bt/rtl8822cu_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .cfg_name = "rtl_bt/rtl8822cu_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* 8822B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) { IC_INFO(RTL_ROM_LMP_8822B, 0xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .config_needed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .fw_name = "rtl_bt/rtl8822b_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .cfg_name = "rtl_bt/rtl8822b_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* 8852B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { IC_INFO(RTL_ROM_LMP_8852A, 0xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .config_needed = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .has_rom_version = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .fw_name = "rtl_bt/rtl8852bu_fw.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .cfg_name = "rtl_bt/rtl8852bu_config" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u8 hci_ver, u8 hci_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) for (i = 0; i < ARRAY_SIZE(ic_id_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if ((ic_id_table[i].match_flags & IC_MATCH_FL_LMPSUBV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) (ic_id_table[i].lmp_subver != lmp_subver))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIREV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) (ic_id_table[i].hci_rev != hci_rev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIVER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) (ic_id_table[i].hci_ver != hci_ver))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) (ic_id_table[i].hci_bus != hci_bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (i >= ARRAY_SIZE(ic_id_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return &ic_id_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) HCI_INIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION failed (%ld)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) PTR_ERR(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (skb->len != sizeof(struct hci_rp_read_local_version)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION event length mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct rtl_rom_version_evt *rom_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* Read RTL ROM version command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rtl_dev_err(hdev, "Read ROM version failed (%ld)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) PTR_ERR(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (skb->len != sizeof(*rom_version)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) rtl_dev_err(hdev, "version event length mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rom_version = (struct rtl_rom_version_evt *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) rtl_dev_info(hdev, "rom_version status=%x version=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) rom_version->status, rom_version->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *version = rom_version->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int rtlbt_parse_firmware(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct btrtl_device_info *btrtl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned char **_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct rtl_epatch_header *epatch_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) size_t min_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u8 opcode, length, data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int project_id = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) const unsigned char *fwptr, *chip_id_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) const unsigned char *patch_length_base, *patch_offset_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) u32 patch_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u16 patch_length, num_patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) __u16 lmp_subver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) __u8 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) } project_id_to_lmp_subver[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) { RTL_ROM_LMP_8723A, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) { RTL_ROM_LMP_8723B, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { RTL_ROM_LMP_8821A, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { RTL_ROM_LMP_8761A, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { RTL_ROM_LMP_8822B, 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { RTL_ROM_LMP_8723B, 9 }, /* 8723D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) { RTL_ROM_LMP_8821A, 10 }, /* 8821C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) { RTL_ROM_LMP_8822B, 13 }, /* 8822C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { RTL_ROM_LMP_8761A, 14 }, /* 8761B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) { RTL_ROM_LMP_8852A, 20 }, /* 8852B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (btrtl_dev->fw_len < min_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) fwptr = btrtl_dev->fw_data + btrtl_dev->fw_len - sizeof(extension_sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) rtl_dev_err(hdev, "extension section signature mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* Loop from the end of the firmware parsing instructions, until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * we find an instruction that identifies the "project ID" for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * hardware supported by this firwmare file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * Once we have that, we double-check that that project_id is suitable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * for the hardware we are working with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) while (fwptr >= btrtl_dev->fw_data + (sizeof(*epatch_info) + 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) opcode = *--fwptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) length = *--fwptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) data = *--fwptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) BT_DBG("check op=%x len=%x data=%x", opcode, length, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (opcode == 0xff) /* EOF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (length == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) rtl_dev_err(hdev, "found instruction with length 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (opcode == 0 && length == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) project_id = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) fwptr -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (project_id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) rtl_dev_err(hdev, "failed to find version instruction");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* Find project_id in table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) for (i = 0; i < ARRAY_SIZE(project_id_to_lmp_subver); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (project_id == project_id_to_lmp_subver[i].id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (i >= ARRAY_SIZE(project_id_to_lmp_subver)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rtl_dev_err(hdev, "unknown project id %d", project_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (btrtl_dev->ic_info->lmp_subver !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) project_id_to_lmp_subver[i].lmp_subver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) rtl_dev_err(hdev, "firmware is for %x but this is a %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) project_id_to_lmp_subver[i].lmp_subver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) btrtl_dev->ic_info->lmp_subver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) epatch_info = (struct rtl_epatch_header *)btrtl_dev->fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) rtl_dev_err(hdev, "bad EPATCH signature");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) num_patches = le16_to_cpu(epatch_info->num_patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) BT_DBG("fw_version=%x, num_patches=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) le32_to_cpu(epatch_info->fw_version), num_patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* After the rtl_epatch_header there is a funky patch metadata section.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * Assuming 2 patches, the layout is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * Find the right patch for this chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) min_size += 8 * num_patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (btrtl_dev->fw_len < min_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) chip_id_base = btrtl_dev->fw_data + sizeof(struct rtl_epatch_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) patch_length_base = chip_id_base + (sizeof(u16) * num_patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) patch_offset_base = patch_length_base + (sizeof(u16) * num_patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) for (i = 0; i < num_patches; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u16 chip_id = get_unaligned_le16(chip_id_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) (i * sizeof(u16)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (chip_id == btrtl_dev->rom_version + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) patch_length = get_unaligned_le16(patch_length_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) (i * sizeof(u16)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) patch_offset = get_unaligned_le32(patch_offset_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) (i * sizeof(u32)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (!patch_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) rtl_dev_err(hdev, "didn't find patch for chip id %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) btrtl_dev->rom_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) min_size = patch_offset + patch_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (btrtl_dev->fw_len < min_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* Copy the firmware into a new buffer and write the version at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * the end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) len = patch_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) buf = kvmalloc(patch_length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) memcpy(buf, btrtl_dev->fw_data + patch_offset, patch_length - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int rtl_download_firmware(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) const unsigned char *data, int fw_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct rtl_download_cmd *dl_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) int frag_num = fw_len / RTL_FRAG_LEN + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) int frag_len = RTL_FRAG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct hci_rp_read_local_version *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (!dl_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) for (i = 0; i < frag_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) BT_DBG("download fw (%d/%d)", i, frag_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (i > 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) dl_cmd->index = (i & 0x7f) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) dl_cmd->index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (i == (frag_num - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dl_cmd->index |= 0x80; /* data end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) frag_len = fw_len % RTL_FRAG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) memcpy(dl_cmd->data, data, frag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* Send download command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) HCI_INIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) rtl_dev_err(hdev, "download fw command failed (%ld)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) PTR_ERR(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ret = PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (skb->len != sizeof(struct rtl_download_response)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) rtl_dev_err(hdev, "download fw event length mismatch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) data += RTL_FRAG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) skb = btrtl_read_local_version(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ret = PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) rtl_dev_err(hdev, "read local version failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) rp = (struct hci_rp_read_local_version *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) rtl_dev_info(hdev, "fw version 0x%04x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) __le16_to_cpu(rp->hci_rev), __le16_to_cpu(rp->lmp_subver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) kfree(dl_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int rtl_load_file(struct hci_dev *hdev, const char *name, u8 **buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) rtl_dev_info(hdev, "loading %s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = request_firmware(&fw, name, &hdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ret = fw->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) *buff = kvmalloc(fw->size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (*buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) memcpy(*buff, fw->data, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int btrtl_setup_rtl8723a(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct btrtl_device_info *btrtl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (btrtl_dev->fw_len < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* Check that the firmware doesn't have the epatch signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * (which is only for RTL8723B and newer).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) rtl_dev_err(hdev, "unexpected EPATCH signature!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return rtl_download_firmware(hdev, btrtl_dev->fw_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) btrtl_dev->fw_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int btrtl_setup_rtl8723b(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct btrtl_device_info *btrtl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) unsigned char *fw_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) u8 *tbuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ret = rtlbt_parse_firmware(hdev, btrtl_dev, &fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (btrtl_dev->cfg_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) tbuff = kvzalloc(ret + btrtl_dev->cfg_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (!tbuff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) memcpy(tbuff, fw_data, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) kvfree(fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) memcpy(tbuff + ret, btrtl_dev->cfg_data, btrtl_dev->cfg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ret += btrtl_dev->cfg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) fw_data = tbuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) rtl_dev_info(hdev, "cfg_sz %d, total sz %d", btrtl_dev->cfg_len, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = rtl_download_firmware(hdev, fw_data, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) kvfree(fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) void btrtl_free(struct btrtl_device_info *btrtl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) kvfree(btrtl_dev->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) kvfree(btrtl_dev->cfg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) kfree(btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) EXPORT_SYMBOL_GPL(btrtl_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) const char *postfix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct btrtl_device_info *btrtl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct hci_rp_read_local_version *resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) char cfg_name[40];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) u16 hci_rev, lmp_subver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) u8 hci_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (!btrtl_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) goto err_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) skb = btrtl_read_local_version(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) ret = PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) resp = (struct hci_rp_read_local_version *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) rtl_dev_info(hdev, "examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x lmp_subver=%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) resp->hci_ver, resp->hci_rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) resp->lmp_ver, resp->lmp_subver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) hci_ver = resp->hci_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) hci_rev = le16_to_cpu(resp->hci_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) lmp_subver = le16_to_cpu(resp->lmp_subver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) hdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!btrtl_dev->ic_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) rtl_dev_info(hdev, "unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) lmp_subver, hci_rev, hci_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return btrtl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (btrtl_dev->ic_info->has_rom_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ret = rtl_read_rom_version(hdev, &btrtl_dev->rom_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) btrtl_dev->fw_len = rtl_load_file(hdev, btrtl_dev->ic_info->fw_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) &btrtl_dev->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (btrtl_dev->fw_len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) rtl_dev_err(hdev, "firmware file %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) btrtl_dev->ic_info->fw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ret = btrtl_dev->fw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (btrtl_dev->ic_info->cfg_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (postfix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) snprintf(cfg_name, sizeof(cfg_name), "%s-%s.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) btrtl_dev->ic_info->cfg_name, postfix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) snprintf(cfg_name, sizeof(cfg_name), "%s.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) btrtl_dev->ic_info->cfg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) btrtl_dev->cfg_len = rtl_load_file(hdev, cfg_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) &btrtl_dev->cfg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (btrtl_dev->ic_info->config_needed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) btrtl_dev->cfg_len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) rtl_dev_err(hdev, "mandatory config file %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) btrtl_dev->ic_info->cfg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ret = btrtl_dev->cfg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return btrtl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) btrtl_free(btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) err_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) EXPORT_SYMBOL_GPL(btrtl_initialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) int btrtl_download_firmware(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct btrtl_device_info *btrtl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* Match a set of subver values that correspond to stock firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * which is not compatible with standard btusb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * If matched, upload an alternative firmware that does conform to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * standard btusb. Once that firmware is uploaded, the subver changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * to a different value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (!btrtl_dev->ic_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) rtl_dev_info(hdev, "assuming no firmware upload needed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) switch (btrtl_dev->ic_info->lmp_subver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case RTL_ROM_LMP_8723A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) case RTL_ROM_LMP_3499:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return btrtl_setup_rtl8723a(hdev, btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) case RTL_ROM_LMP_8723B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) case RTL_ROM_LMP_8821A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) case RTL_ROM_LMP_8761A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) case RTL_ROM_LMP_8822B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) case RTL_ROM_LMP_8852A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return btrtl_setup_rtl8723b(hdev, btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) rtl_dev_info(hdev, "assuming no firmware upload needed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) EXPORT_SYMBOL_GPL(btrtl_download_firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int btrtl_setup_realtek(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct btrtl_device_info *btrtl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) btrtl_dev = btrtl_initialize(hdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (IS_ERR(btrtl_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return PTR_ERR(btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ret = btrtl_download_firmware(hdev, btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) btrtl_free(btrtl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /* Enable controller to do both LE scan and BR/EDR inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * simultaneously.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int btrtl_shutdown_realtek(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* According to the vendor driver, BT must be reset on close to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * firmware crash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ret = PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) bt_dev_err(hdev, "HCI reset during shutdown failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) EXPORT_SYMBOL_GPL(btrtl_shutdown_realtek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static unsigned int btrtl_convert_baudrate(u32 device_baudrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) switch (device_baudrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) case 0x0252a00a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return 230400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) case 0x05f75004:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return 921600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) case 0x00005004:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) case 0x04928002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) case 0x01128002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return 1500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) case 0x00005002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return 2000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) case 0x0000b001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return 2500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) case 0x04928001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return 3000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case 0x052a6001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return 3500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) case 0x00005001:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return 4000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) case 0x0252c014:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return 115200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int btrtl_get_uart_settings(struct hci_dev *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct btrtl_device_info *btrtl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) unsigned int *controller_baudrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) u32 *device_baudrate, bool *flow_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct rtl_vendor_config *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct rtl_vendor_config_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) int i, total_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) total_data_len = btrtl_dev->cfg_len - sizeof(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (total_data_len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) rtl_dev_warn(hdev, "no config loaded");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) config = (struct rtl_vendor_config *)btrtl_dev->cfg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (le32_to_cpu(config->signature) != RTL_CONFIG_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) rtl_dev_err(hdev, "invalid config magic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (total_data_len < le16_to_cpu(config->total_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) rtl_dev_err(hdev, "config is too short");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) for (i = 0; i < total_data_len; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) entry = ((void *)config->entry) + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) switch (le16_to_cpu(entry->offset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case 0xc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (entry->len < sizeof(*device_baudrate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) rtl_dev_err(hdev, "invalid UART config entry");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) *device_baudrate = get_unaligned_le32(entry->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) *controller_baudrate = btrtl_convert_baudrate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) *device_baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (entry->len >= 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) *flow_control = !!(entry->data[12] & BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) *flow_control = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) rtl_dev_dbg(hdev, "skipping config entry 0x%x (len %u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) le16_to_cpu(entry->offset), entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) i += sizeof(*entry) + entry->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) rtl_dev_err(hdev, "no UART config entry found");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) rtl_dev_dbg(hdev, "device baudrate = 0x%08x", *device_baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) rtl_dev_dbg(hdev, "controller baudrate = %u", *controller_baudrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) rtl_dev_dbg(hdev, "flow control %d", *flow_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) EXPORT_SYMBOL_GPL(btrtl_get_uart_settings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) MODULE_VERSION(VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) MODULE_FIRMWARE("rtl_bt/rtl8723a_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) MODULE_FIRMWARE("rtl_bt/rtl8723bs_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) MODULE_FIRMWARE("rtl_bt/rtl8723bs_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) MODULE_FIRMWARE("rtl_bt/rtl8761a_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) MODULE_FIRMWARE("rtl_bt/rtl8821a_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) MODULE_FIRMWARE("rtl_bt/rtl8821a_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) MODULE_FIRMWARE("rtl_bt/rtl8822b_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) MODULE_FIRMWARE("rtl_bt/rtl8822b_config.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");